Transaction Hash:
Block:
17523619 at Jun-20-2023 09:37:11 PM +UTC
Transaction Fee:
0.001018489932868588 ETH
$2.85
Gas Used:
58,334 Gas / 17.459627882 Gwei
Emitted Events:
33 |
Proxy.0x06724742ccc8c330a39a641ef02a0b419bd09248360680bb38159b0a8c2635d6( 0x06724742ccc8c330a39a641ef02a0b419bd09248360680bb38159b0a8c2635d6, 000000000000000000000000b2cc9b9bc2bd4a88e7c23d8ee64ac6d1af97ea20, 03c8e6dae9ba7ac07c46b5e751d002a03e84603002be4da46baa55e79f37327a, 0000000000000000000000000000000000000000000000000000000067223699, 00b333e3142fe16b78628f19bb15afddaef437e72d6d7f5c6c20c6801a27fba6, 00000000000000000000000000000000000000000000000000071afd498d0000, 0000000000000000000000000000000000000000000000000000000000030d40 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x1f9090aa...8e676c326
Miner
| 7.612791901383761213 Eth | 7.612937736383761213 Eth | 0.000145835 | ||
0x5d22045D...Fad24609b | (Rhino.fi: Bridge) | 1,479.09345213 Eth | 1,479.09545213 Eth | 0.002 | |
0xB2CC9B9B...1Af97EA20 |
0.032761638978532392 Eth
Nonce: 11
|
0.029743149045663804 Eth
Nonce: 12
| 0.003018489932868588 |
Execution Trace
ETH 0.002
Proxy.00aeef8a( )
ETH 0.002
StarkExchange.00aeef8a( )
- ETH 0.002
TokensAndRamping.deposit( starkKey=1711901262248088474928654463891211485670863099518083318923628238314665357946, assetType=316623735692853304525146192642758839706355829840274185964789512850136103846, vaultId=1730295449 )
- ETH 0.002
File 1 of 3: Proxy
File 2 of 3: StarkExchange
File 3 of 3: TokensAndRamping
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*/\npragma solidity ^0.5.2;\n\n/*\n Common Utility libraries.\n 1. Addresses (extendingaddress).\n*/\nlibrary Addresses {\n function isContract(address account) internal view returns (bool) {\n uint256 size;\n //solium-disable-next-line security/no-inline-assembly\n assembly {\n size := extcodesize(account)\n }\n return size\u003e 0;\n }\n}\n"},"Governance.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*/\npragma solidity ^0.5.2;\n\nimport \"GovernanceStorage.sol\";\nimport \"MGovernance.sol\";\n\n/*\n Implements Generic Governance, applicable for both proxy and main contract, and possibly others.\n Notes:\n 1. This class is virtual (getGovernanceTag is not implemented).\n 2. The use of the same function names by both the Proxy and a delegatedimplementation\n is not possible since calling the implementation functions is done via the default function\n of the Proxy. For thisreason, for example, the implementation of MainContract (MainGovernance)\n exposes mainIsGovernor, which calls the internal isGovernor method.\n*/\ncontract Governance is GovernanceStorage, MGovernance {\n event LogNominatedGovernor(address nominatedGovernor);\n eventLogNewGovernorAccepted(address acceptedGovernor);\n event LogRemovedGovernor(address removedGovernor);\n event LogNominationCancelled();\n\naddress internal constant ZERO_ADDRESS = address(0x0);\n\n /*\n Returns a string which uniquely identifies the type of the governancemechanism.\n */\n function getGovernanceTag()\n internal\n view\n returns (string memory);\n\n /*\n Returns theGovernanceInfoStruct associated with the governance tag.\n */\n function contractGovernanceInfo()\n internal\n view\nreturns (GovernanceInfoStruct storage) {\n string memory tag = getGovernanceTag();\n GovernanceInfoStruct storage gub =governanceInfo[tag];\n require(gub.initialized == true, \"NOT_INITIALIZED\");\n return gub;\n }\n\n function initGovernance()\ninternal\n {\n string memory tag = getGovernanceTag();\n GovernanceInfoStruct storage gub = governanceInfo[tag];\nrequire(gub.initialized == false, \"ALREADY_INITIALIZED\");\n gub.initialized = true; // to ensure addGovernor() won\u0027t fail.\n// Add the initial governer.\n addGovernor(msg.sender);\n }\n\n modifier onlyGovernance()\n {\n require(isGovernor(msg.sender), \"ONLY_GOVERNANCE\");\n _;\n }\n\n function isGovernor(address testGovernor)\n internal view\n returns (booladdressIsGovernor){\n GovernanceInfoStruct storage gub = contractGovernanceInfo();\n addressIsGovernor = gub.effectiveGovernors[testGovernor];\n }\n\n /*\n Cancels the nomination of a governor condidate.\n */\n function cancelNomination()internal onlyGovernance() {\n GovernanceInfoStruct storage gub = contractGovernanceInfo();\n gub.candidateGovernor = ZERO_ADDRESS;\nemit LogNominationCancelled();\n }\n\n function nominateNewGovernor(address newGovernor) internal onlyGovernance() {\nGovernanceInfoStruct storage gub = contractGovernanceInfo();\n require(isGovernor(newGovernor) == false, \"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 Thedifference is that the init path skips the nominate step\n that would fail because of the onlyGovernance modifier.\n */\n functionaddGovernor(address newGovernor) private {\n require(isGovernor(newGovernor) == false, \"ALREADY_GOVERNOR\");\n GovernanceInfoStructstorage gub = contractGovernanceInfo();\n gub.effectiveGovernors[newGovernor] = true;\n }\n\n function acceptGovernance()\ninternal\n {\n // The new governor was proposed 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.\naddGovernor(gub.candidateGovernor);\n gub.candidateGovernor = ZERO_ADDRESS;\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\");\nGovernanceInfoStruct 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,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*/\npragma solidity ^0.5.2;\n\n/*\n Holds the governance slots for ALL entities, includingproxy and the main contract.\n*/\ncontract GovernanceStorage {\n\n struct GovernanceInfoStruct {\n mapping (address =\u003e bool)effectiveGovernors;\n address candidateGovernor;\n bool initialized;\n }\n\n // A map from a Governor tag to its ownGovernanceInfoStruct.\n mapping (string =\u003e GovernanceInfoStruct) internal governanceInfo;\n}\n"},"MGovernance.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*/\npragma solidity ^0.5.2;\n\ncontract MGovernance {\n /*\n Allows calling the function only by a Governor.\n */\n modifier onlyGovernance()\n {\n // Pure modifier declarations are not supported. Instead we provide\n // a dummydefinition.\n revert(\"UNIMPLEMENTED\");\n _;\n }\n}\n"},"Proxy.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*/\npragma solidity^0.5.2;\n\nimport \"ProxyGovernance.sol\";\nimport \"ProxyStorage.sol\";\nimport \"Common.sol\";\n\n/**\n The Proxy contract implements delegationof calls to other contracts (`implementations`), with\n proper forwarding of return values and revert reasons. This pattern allows retaining thecontract\n storage while replacing implementation code.\n\n The following operations are supported by the proxy contract:\n\n - :sol:func:`addImplementation`: Defines a new implementation, the data with which it should be initialized and whether this will be the last version ofimplementation.\n - :sol:func:`upgradeTo`: Once an implementation is added, the governor may upgrade to that implementation only after a safetytime period has passed (time lock), 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 especiallyimportant once it has been used for an upgrade in order to avoid an additional unwanted revert to an older version.\n\n The only entity allowed toperform the above operations is the proxy governor\n (see :sol:mod:`ProxyGovernance`).\n\n Every implementation is required to have an`initialize` function that replaces the constructor\n of a normal contract. Furthermore, the only parameter of this function is an array ofbytes\n (`data`) which may be decoded arbitrarily by the `initialize` function. It is up to the\n implementation to ensure that this functioncannot be run more than once if so desired.\n\n When an implementation is added (:sol:func:`addImplementation`) the initialization `data` isalso\n announced, allowing users of the contract to analyze the full effect of an upgrade to the new\n implementation. During an :sol:func:`upgradeTo`, the `data` is provided again and only if it is\n identical to the announced `data` is the upgrade performed by pointing the proxy tothe new\n implementation and calling its `initialize` function with this `data`.\n\n It is the responsibility of the implementation not tooverwrite any storage belonging to the\n proxy (`ProxyStorage`). In addition, upon upgrade, the new implementation is assumed to be\n backwardcompatible with previous implementations with respect to the storage used until that\n point.\n*/\ncontract Proxy is ProxyStorage, ProxyGovernance{\n\n // Emitted when the active implementation is replaced.\n event Upgraded(address indexed implementation);\n\n // Emitted when animplementation is submitted as an upgrade candidate and a time lock\n // is activated.\n event ImplementationAdded(address indexedimplementation, bytes initializer, bool finalize);\n\n // Emitted when an implementation is removed from the list of upgrade candidates.\nevent ImplementationRemoved(address indexed implementation);\n\n // Emitted when the implementation is finalized.\n eventFinalizedImplementation(address indexed implementation);\n\n // Storage slot with the address of the current implementation.\n // The addressof 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 logical implementaiton (the proxied contract).\n bytes32 internal constant IMPLEMENTATION_SLOT =\n0x177667240aeeea7e35eabe3a35e18306f336219e1386f7710a6bf8783f761b24;\n\n // This storage slot stores the finalization flag.\n // Once thevalue stored in this slot is set to non-zero\n // the proxy blocks implementation upgrades.\n // The current implementation is then referredto as Finalized.\n // Web3.solidityKeccak([\u0027string\u0027], [\"StarkWare2019.finalization-flag-slot\"]).\n bytes32 internal constantFINALIZED_STATE_SLOT =\n 0x7d433c6f837e8f93009937c466c82efbb5ba621fae36886d0cac433c5d0aa7d2;\n uint256 public constantUPGRADE_ACTIVATION_DELAY = 28 days;\n\n using Addresses for address;\n\n constructor ( )\n public\n {\n initGovernance();\n}\n\n /*\n Returns true if the implementation is frozen.\n If the implementation was not assigned yet, returns false.\n */\nfunction implementationIsFrozen() private returns (bool) {\n address _implementation = implementation();\n\n // We can\u0027t calllow level implementation before it\u0027s assigned. (i.e. ZERO).\n if (_implementation == ZERO_ADDRESS) {\n return false;\n}\n // solium-disable-next-line security/no-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 Only upgradeTo should be able to delegate callto 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 /*\nForbids calling the function if the implementation is frozen.\n This modifier relies on the lower level (logical contract) implementationof isFrozen().\n */\n modifier notFrozen()\n {\n require(implementationIsFrozen() == false, \"STATE_IS_FROZEN\");\n _;\n}\n\n /*\n Contract\u0027s default function. Delegates execution to the implementation contract.\n It returns back to the externalcaller whatever the implementation delegated code returns.\n */\n function () external payable {\n address _implementation =implementation();\n require (_implementation != ZERO_ADDRESS, \"MISSING_IMPLEMENTATION\");\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // blockbecause it will not return to 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\u0027t know the out sizeyet.\n let result := delegatecall(gas, _implementation, 0, calldatasize, 0, 0)\n\n // Copy the returned data.\nreturndatacopy(0, 0, returndatasize)\n\n switch result\n // delegatecall returns 0 on error.\n case 0 { revert(0,returndatasize) }\n default { return(0, returndatasize) }\n }\n }\n\n /*\n Returns the address of the currentimplementation.\n */\n function implementation() public view returns (address _implementation) {\n bytes32 slot = IMPLEMENTATION_SLOT;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n _implementation := sload(slot)\n }\n}\n\n /*\n Sets the implementation address of the proxy.\n */\n function setImplementation(address newImplementation) private {\nbytes32 slot = IMPLEMENTATION_SLOT;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n sstore(slot, newImplementation)\n }\n }\n\n /*\n Returns true if the contract is not in the finalized state.\n */\n functionisNotFinalized() public view returns (bool notFinal) {\n bytes32 slot = FINALIZED_STATE_SLOT;\n uint256 slotValue;\n // solium-disable-next-line security/no-inline-assembly\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 {\n bytes32slot = FINALIZED_STATE_SLOT;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n sstore(slot, 0x1)\n}\n }\n\n /*\n Introduce an implementation and its initialization vector,\n and start the time-lock before it can beupgraded to.\n addImplementation is not blocked when frozen or finalized.\n (upgradeTo API is blocked when finalized or frozen).\n*/\n function addImplementation(address newImplementation, bytes calldata data, bool finalize)\n external onlyGovernance {\nrequire(newImplementation.isContract(), \"ADDRESS_NOT_CONTRACT\");\n\n bytes32 init_hash = keccak256(abi.encode(data, finalize));\ninitializationHash[newImplementation] = init_hash;\n\n // solium-disable-next-line security/no-block-members\n uint256activation_time = now + UPGRADE_ACTIVATION_DELAY;\n\n // First implementation should not have time-lock.\n if (implementation() ==ZERO_ADDRESS) {\n // solium-disable-next-line security/no-block-members\n activation_time = now;\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 inititalizing vector (even if empty).\n Therefore, the implementatinMUST must have such a method.\n */\n function upgradeTo(address newImplementation, bytes calldata data, bool finalize)\n externalpayable onlyGovernance notFinalized notFrozen {\n uint256 activation_time = enabledTime[newImplementation];\n\n require(activation_time \u003e 0, \"ADDRESS_NOT_UPGRADE_CANDIDATE\");\n // solium-disable-next-line security/no-block-members\n require(activation_time \u003c= now, \"UPGRADE_NOT_ENABLED_YET\");\n\n bytes32 init_vector_hash = initializationHash[newImplementation];\nrequire(init_vector_hash == keccak256(abi.encode(data, finalize)), \"CHANGED_INITIALIZER\");\n setImplementation(newImplementation);\n\n// solium-disable-next-line security/no-low-level-calls\n (bool success, bytes memory returndata) = newImplementation.delegatecall(\nabi.encodeWithSelector(this.initialize.selector, data));\n require(success, string(returndata));\n\n // Verify that the newimplementation is not frozen post initialization.\n (success, returndata) = newImplementation.delegatecall(\n abi.encodeWithSignature(\"isFrozen()\"));\n require(success, \"CALL_TO_ISFROZEN_REVERTED\");\n require(abi.decode(returndata, (bool)) ==false, \"NEW_IMPLEMENTATION_FROZEN\");\n\n if (finalize == true) {\n setFinalizedFlag();\n emitFinalizedImplementation(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 usethis 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\nUnless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES 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*/\npragma solidity ^0.5.2;\n\nimport \"Governance.sol\";\n\n/**\n The Proxy contract is governed by one or moreGovernors of which the initial one is the\n deployer of the contract.\n\n A governor has the sole authority to perform the 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 allowsit\n\n Adding governors is performed in a two step procedure:\n\n 1. First, an existing governor nominates a new governor (:sol:func:`proxyNominateNewGovernor`)\n 2. Then, the new governor must accept governance to become a governor (:sol:func:`proxyAcceptGovernance`)\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 or managedvia a\n multi-sig contract.\n*/\n/*\n Implements Governance for the proxy contract.\n It is a thin wrapper to the Governance contract,\n whichis needed so that it can have non-colliding function names,\n and a specific tag (key) to allow unique state storage.\n*/\ncontractProxyGovernance is Governance {\n\n // The tag is the string key that is used in the Governance storage mapping.\n string public constantPROXY_GOVERNANCE_TAG = \"StarkEx.Proxy.2019.GovernorsInformation\";\n\n function getGovernanceTag()\n internal\n view\nreturns (string memory tag) {\n tag = PROXY_GOVERNANCE_TAG;\n }\n\n function proxyIsGovernor(address testGovernor) external viewreturns (bool) {\n return isGovernor(testGovernor);\n }\n\n function proxyNominateNewGovernor(address newGovernor) external {\nnominateNewGovernor(newGovernor);\n }\n\n function proxyRemoveGovernor(address governorForRemoval) external {\n removeGovernor(governorForRemoval);\n }\n\n function proxyAcceptGovernance()\n external\n {\n acceptGovernance();\n }\n\n functionproxyCancelNomination() external {\n cancelNomination();\n }\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*/\npragma solidity ^0.5.2;\n\nimport \"GovernanceStorage.sol\";\n\n/*\n Holds the Proxy-specific state variables.\n This contract is inheritedby the GovernanceStorage (and indirectly by MainStorage)\n to prevent collision hazard.\n*/\ncontract ProxyStorage is GovernanceStorage {\n\n// Stores the hash of the initialization vector of the added implementation.\n // Upon upgradeTo the implementation, the initialization vectoris verified\n // to be identical to the one submitted when adding the implementaion.\n mapping (address =\u003e bytes32) internalinitializationHash;\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 can be used flexibly enough to accomodatemultiple level of initialization\n // (i.e. using different key salting schemes for different initialization levels).\n mapping (bytes32=\u003e bool) internal initialized;\n}\n"}}
File 2 of 3: StarkExchange
1{"BlockDirectCall.sol":{"content":"/*\n Copyright 2019-2021 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\n/*\nThis contract provides means to block direct call of an external function.\n A derived contract (e.g. MainDispatcherBase) should decoratesensitive functions with the\n notCalledDirectly modifier, thereby preventing it from being called directly, and allowing only calling\n usingdelegate_call.\n\n This Guard contract uses pseudo-random slot, So each deployed contract would have its own guard.\n*/\nabstract contractBlockDirectCall {\n bytes32 immutable UNIQUE_SAFEGUARD_SLOT; // NOLINT naming-convention.\n\n constructor() internal {\n // The slotis pseudo-random to allow hierarchy of contracts with guarded functions.\n bytes32 slot = keccak256(abi.encode(this, block.timestamp,gasleft()));\n UNIQUE_SAFEGUARD_SLOT = slot;\n assembly {\n sstore(slot, 42)\n }\n }\n\n modifiernotCalledDirectly() {\n {\n // Prevent too many local variables in stack.\n uint256 safeGuardValue;\nbytes32 slot = UNIQUE_SAFEGUARD_SLOT;\n assembly {\n safeGuardValue := sload(slot)\n }\n require(safeGuardValue == 0, \"DIRECT_CALL_DISALLOWED\");\n }\n _;\n }\n}\n"},"Common.sol":{"content":"/*\n Copyright 2019-2021StarkWare 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 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 {\nsize := extcodesize(account)\n }\n return size \u003e 0;\n }\n\n function performEthTransfer(address recipient, uint256amount) 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 ERC20contracts 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 Validates that the passed contract address is of a real contract,\n and that its id hash (as infered fromnidentify()) matched the expected one.\n */\n function validateContractId(address contractAddress, bytes32 expectedIdHash) internal {\nrequire(isContract(contractAddress), \"ADDRESS_NOT_CONTRACT\");\n (bool success, bytes memory returndata) = contractAddress.call( // NOLINT: low-level-calls.\n abi.encodeWithSignature(\"identify()\")\n );\n require(success, \"FAILED_TO_IDENTIFY_CONTRACT\");\nstring memory realContractId = abi.decode(returndata, (string));\n require(\n keccak256(abi.encodePacked(realContractId))== expectedIdHash,\n \"UNEXPECTED_CONTRACT_IDENTIFIER\"\n );\n }\n}\n\n/*\n II. StarkExTypes - Common data types.\n*/\nlibrary StarkExTypes {\n // Structure representing a list of verifiers (validity/availability).\n // A statement is valid only if all theverifiers in the list agree on it.\n // Adding a verifier to the list is immediate - this is used for fast resolution of\n // any soundnessissues.\n // Removing from the list is time-locked, to ensure that any user of the system\n // not content with the announced removal hasample time to leave the system before it is\n // removed.\n struct ApprovalChainData {\n address[] list;\n // Represents thetime after which the verifier with the given address can be removed.\n // Removal of the verifier with address A is allowed only in the casethe value\n // of unlockedForRemovalTime[A] != 0 and unlockedForRemovalTime[A] \u003c (current time).\n mapping(address =\u003euint256) unlockedForRemovalTime;\n }\n}\n"},"GovernanceStorage.sol":{"content":"/*\n Copyright 2019-2021 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\n/*\n Holds the governance slots for ALL entities, including proxy and the main contract.\n*/\ncontract GovernanceStorage {\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-2021 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 Allows a caller, typically another contract,\n toensure that the provided address is of the expected type and version.\n */\n function identify() external pure returns (string memory);\n}\n"},"IDispatcherBase.sol":{"content":"/*\n Copyright 2019-2021 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\n/*\nInterface for generic dispatcher to use,\n which the concrete dispatcher must implement.\n\n I contains the functions that are specific to theconcrete dispatcher instance.\n\n The interface is implemented as contract, because interface implies all methods external.\n*/\nabstract contractIDispatcherBase {\n function getSubContract(bytes4 selector) internal view virtual returns (address);\n\n function setSubContractAddress(uint256 index, address subContract) internal virtual;\n\n function getNumSubcontracts() internal pure virtual returns (uint256);\n\nfunction validateSubContractIndex(uint256 index, address subContract) internal pure virtual;\n\n /*\n Ensures initializer can be called.Reverts otherwise.\n */\n function initializationSentinel() internal view virtual;\n}\n"},"MainDispatcher.sol":{"content":"/*\n Copyright2019-2021 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 \"MainStorage.sol\";\nimport \"MainDispatcherBase.sol\";\n\nabstract contract MainDispatcher is MainStorage, MainDispatcherBase {\n uint256 constant SUBCONTRACT_BITS = 4;\n\n function magicSalt()internal pure virtual returns (uint256);\n\n function handlerMapSection(uint256 section) internal view virtual returns (uint256);\n\nfunction expectedIdByIndex(uint256 index) internal pure virtual returns (string memory id);\n\n function validateSubContractIndex(uint256 index,address subContract) internal pure override {\n string memory id = SubContractor(subContract).identify();\n bytes32hashed_expected_id = keccak256(abi.encodePacked(expectedIdByIndex(index)));\n require(\n hashed_expected_id == keccak256(abi.encodePacked(id)),\n \"MISPLACED_INDEX_OR_BAD_CONTRACT_ID\"\n );\n }\n\n function getSubContract(bytes4 selector) internalview override returns (address) {\n uint256 location = 0xFF \u0026 uint256(keccak256(abi.encodePacked(selector, magicSalt())));\nuint256 subContractIdx;\n uint256 offset = (SUBCONTRACT_BITS * location) % 256;\n\n // We have 64 locations in each register, hencethe \u003e\u003e6 (i.e. location // 64).\n subContractIdx = (handlerMapSection(location \u003e\u003e 6) \u003e\u003e offset) \u0026 0xF;\nreturn subContracts[subContractIdx];\n }\n\n function setSubContractAddress(uint256 index, address subContractAddress) internaloverride {\n subContracts[index] = subContractAddress;\n }\n}\n"},"MainDispatcherBase.sol":{"content":"/*\n Copyright 2019-2021StarkWare 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 \"SubContractor.sol\";\nimport \"IDispatcherBase.sol\";\nimport\"BlockDirectCall.sol\";\nimport \"Common.sol\";\n\nabstract contract MainDispatcherBase is IDispatcherBase, BlockDirectCall {\n using Addressesfor address;\n\n /*\n This entry point serves only transactions with empty calldata. (i.e. pure value transfer tx).\n We don\u0027texpect to receive such, thus block them.\n */\n receive() external payable {\n revert(\"CONTRACT_NOT_EXPECTED_TO_RECEIVE\");\n}\n\n fallback() external payable {\n address subContractAddress = getSubContract(msg.sig);\n require(subContractAddress !=address(0x0), \"NO_CONTRACT_FOR_FUNCTION\");\n\n assembly {\n // Copy msg.data. We take full control of memory in this inlineassembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memoryposition 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 fornow, 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 0on error.\n case 0 {\n revert(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-contract initializer data.\n 4. Call sub-contract initializer.\n\n The init data bytes passed to initialize arestructed as following:\n I. N slots (uin256 size) addresses of the deployed sub-contracts.\n II. An address of an external initializationcontract (optional, or ZERO_ADDRESS).\n III. (Up to) N bytes sections of the sub-contracts initializers.\n\n If already initialized (i.e.upgrade) we expect the init data to be consistent with this.\n and if a different size of init data is expected when upgrading, theinitializerSize should\n reflect this.\n\n If an external initializer contract is not used, ZERO_ADDRESS is passed in its slot.\n Ifthe external initializer contract is used, all the remaining init data is passed to it,\n and internal initialization will not occur.\n\nExternal Initialization Contract\n --------------------------------\n External Initialization Contract (EIC) is a hook for custominitialization.\n Typically in an upgrade flow, the expected initialization contains only the addresses of\n the sub-contracts. Normalinitialization 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 aworking system\n may corrupt it.\n\n In the event that some state initialization is required, the EIC is a hook that allows this.\nIt may be deployed and called specifically for this purpose.\n\n The address of the EIC must be provided (if at all) when a new implementationis added to\n a Proxy contract (as part of the initialization vector).\n Hence, it is considered part of the code open to reviewers priorto a time-locked upgrade.\n\n When a custom initialization is performed using an EIC,\n the main dispatcher initialize extracts andstores the sub-contracts addresses, and then\n yields to the EIC, skipping the rest of its initialization code.\n\n\n Flow ofMainDispatcher initialize\n ---------------------------------\n 1. Extraction and assignment of subcontracts addresses\n Maindispatcher expects a valid and consistent set of addresses in the passed data.\n It validates that, extracts the addresses from the data,and validates that the addresses\n are of the expected type and order. Then those addresses are stored.\n\n 2. Extraction of EICaddress\n The address of the EIC is extracted from the data.\n External Initializer Contract is optional. ZERO_ADDRESS indicates itis not used.\n\n 3a. EIC is used\n Dispatcher calls the EIC initialize function with the remaining data.\n Note - In thisoption 3b is not performed.\n\n 3b. EIC is not used\n If there is additional initialization data then:\n I. Sentitenlfunction is called to permit subcontracts initialization.\n II. Dispatcher loops through the subcontracts and for each one it extractsthe\n initializing data and passes it to the subcontract\u0027s initialize function.\n\n */\n function initialize(bytes calldatadata) external virtual notCalledDirectly {\n // Number of sub-contracts.\n uint256 nSubContracts = 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 // Sum of subcontract initializers. Aggregated for verification near the end.\n uint256totalInitSizes = 0;\n\n // Offset (within data) of sub-contract initializer vector.\n // Just past the sub-contract+eic addresses.\nuint256 initDataContractsOffset = 32 * (nSubContracts + 1);\n\n // Init data MUST include addresses for all sub-contracts + EIC.\nrequire(data.length \u003e= initDataContractsOffset, \"SUB_CONTRACTS_NOT_PROVIDED\");\n\n // Size of passed data, excluding sub-contract addresses.\n uint256 additionalDataSize = data.length - initDataContractsOffset;\n\n // Extract \u0026 update contractaddresses.\n for (uint256 nContract = 1; nContract \u003c= nSubContracts; nContract++) {\n // Extract sub-contract address.\naddress contractAddress = abi.decode(\n data[32 * (nContract - 1):32 * nContract],\n (address)\n);\n\n validateSubContractIndex(nContract, contractAddress);\n\n // Contracts are indexed from 1 and 0 is not in use here.\nsetSubContractAddress(nContract, contractAddress);\n }\n\n // Check if we have an external initializer contract.\naddress externalInitializerAddr = abi.decode(\n data[initDataContractsOffset - 32:initDataContractsOffset],\n (address)\n);\n\n // 3(a). Yield to EIC initialization.\n if (externalInitializerAddr != address(0x0)) {\ncallExternalInitializer(externalInitializerAddr, data[initDataContractsOffset:]);\n return;\n }\n\n // 3(b). Subcontractsinitialization.\n // I. If no init data passed besides sub-contracts, return.\n if (additionalDataSize == 0) {\n return;\n}\n\n // Just to be on the safe side.\n assert(externalInitializerAddr == address(0x0));\n\n // II. Gate furtherinitialization.\n initializationSentinel();\n\n // III. Loops through the subcontracts, extracts their data and calls theirinitializer.\n for (uint256 nContract = 1; nContract \u003c= nSubContracts; nContract++) {\n // Extract sub-contract address.\naddress contractAddress = abi.decode(\n data[32 * (nContract - 1):32 * nContract],\n (address)\n);\n\n // The initializerSize is called via delegatecall, so that it can relate to the state,\n // and not only to the newcontract code. (e.g. return 0 if state-intialized else 192).\n // NOLINTNEXTLINE: controlled-delegatecall low-level-calls calls-loop.\n(bool success, bytes memory returndata) = contractAddress.delegatecall(\n abi.encodeWithSelector(SubContractor(contractAddress).initializerSize.selector)\n );\n require(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 // Call sub-contract initializer.\n // NOLINTNEXTLINE: controlled-delegatecall calls-loop.\n(success, returndata) = contractAddress.delegatecall(\n abi.encodeWithSelector(\n this.initialize.selector,\ndata[initDataContractsOffset:initDataContractsOffset + initSize]\n )\n );\n require(success,string(returndata));\n totalInitSizes += initSize;\n initDataContractsOffset += initSize;\n }\n require(additionalDataSize == totalInitSizes, \"MISMATCHING_INIT_DATA_SIZE\");\n }\n\n function callExternalInitializer(addressexternalInitializerAddr, bytes calldata extInitData)\n private\n {\n require(externalInitializerAddr.isContract(),\"NOT_A_CONTRACT\");\n\n // NOLINTNEXTLINE: low-level-calls, controlled-delegatecall.\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-2021 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 \"ProxyStorage.sol\";\nimport\"Common.sol\";\n\n/*\n Holds ALL the main contract state (storage) variables.\n*/\ncontract MainStorage is ProxyStorage {\n uint256 internalconstant LAYOUT_LENGTH = 2**64;\n\n address escapeVerifierAddress; // NOLINT: constable-states.\n\n // Global dex-frozen flag.\n boolstateFrozen; // NOLINT: constable-states.\n\n // Time when unFreeze can be successfully called (UNFREEZE_DELAY after freeze).\n uint256unFreezeTime; // NOLINT: constable-states.\n\n // Pending deposits.\n // A map STARK key =\u003e asset id =\u003e vault id =\u003e quantizedamount.\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 =\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.\n mapping(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 // NOLINTNEXTLINE naming-convention.\n mapping(uint256 =\u003e mapping(uint256 =\u003e uint256)) fullWithdrawalRequests_DEPRECATED;\n\n // State sequence number.\nuint256 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-states uninitialized-state.\n\n // Order TreeRoot \u0026 Height.\n uint256 orderRoot; // NOLINT: constable-states uninitialized-state.\n uint256 orderTreeHeight; // NOLINT: constable-states uninitialized-state.\n\n // True if and only if the address is allowed to add tokens.\n mapping(address =\u003e bool) tokenAdmins;\n\n // This mapping is no longer in use, remains for backwards compatibility.\n mapping(address =\u003e bool) userAdmins_DEPRECATED; //NOLINT: naming-convention.\n\n // True if and only if the address is an operator (allowed to update state).\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 // Thismapping is no longer in use, remains for backwards compatibility.\n mapping(address =\u003e uint256) starkKeys_DEPRECATED; // NOLINT: naming-convention.\n\n // Mapping from STARK public 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.ApprovalChainDataverifiersChain;\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=\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.\nuint256 onchainDataVersion; // NOLINT: constable-states uninitialized-state.\n\n // Counter of forced action request in block. The key is theblock number.\n mapping(uint256 =\u003e uint256) forcedRequestsInBlock;\n\n // ForcedAction requests: actionHash =\u003e requestTime.\nmapping(bytes32 =\u003e uint256) forcedActionRequests;\n\n // Mapping for timelocked actions.\n // A actionKey =\u003e activation time.\nmapping(bytes32 =\u003e uint256) actionsTimeLock;\n\n // Append only list of requested forced action hashes.\n bytes32[] actionHashList;\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.\n uint256[LAYOUT_LENGTH - 37] private __endGap; // __endGap complements layout toLAYOUT_LENGTH.\n}\n"},"ProxyStorage.sol":{"content":"/*\n Copyright 2019-2021 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 \"GovernanceStorage.sol\";\n\n/*\n Holds the Proxy-specific state variables.\n This contract is inherited by theGovernanceStorage (and indirectly by MainStorage)\n to prevent collision hazard.\n*/\ncontract ProxyStorage is GovernanceStorage {\n //NOLINTNEXTLINE: naming-convention uninitialized-state.\n mapping(address =\u003e bytes32) internal initializationHash_DEPRECATED;\n\n // Thetime after which we can switch to the implementation.\n // Hash(implementation, data, finalize) =\u003e time.\n mapping(bytes32 =\u003euint256) internal enabledTime;\n\n // A central storage of the flags whether implementation has been initialized.\n // Note - it can be usedflexibly enough to accommodate multiple levels of initialization\n // (i.e. using different key salting schemes for different initializationlevels).\n mapping(bytes32 =\u003e bool) internal initialized;\n}\n"},"StarkExchange.sol":{"content":"/*\n Copyright 2019-2021 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 \"MainDispatcher.sol\";\n\ncontract StarkExchange is MainDispatcher {\nstring public constant VERSION = \"4.0.1\";\n\n // Salt for a 8 bit unique spread of all relevant selectors. Pre-caclulated.\n // ----------The following code was auto-generated. PLEASE DO NOT EDIT. ----------\n uint256 constant MAGIC_SALT = 46110;\n uint256 constant IDX_MAP_0 =0x30006100050005012000102002000001200000010001100500200000000020;\n uint256 constant IDX_MAP_1 =0x120000105000000501200000120502000000200452005000202002030500003;\n uint256 constant IDX_MAP_2 =0x1020000000003020000502203000300000200000000001000100330010220001;\n uint256 constant IDX_MAP_3 =0x200230200020300001401200000000100020011200000002020000010000301;\n\n // ---------- End of auto-generated code. ----------\n\n functiongetNumSubcontracts() internal pure override returns (uint256) {\n return 6;\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 } else if (section == 1) {\n return IDX_MAP_1;\n } else if(section == 2) {\n return IDX_MAP_2;\n } else if (section == 3) {\n return IDX_MAP_3;\n }\n revert(\"BAD_IDX_MAP_SECTION\");\n }\n\n function expectedIdByIndex(uint256 index) internal pure override returns (string memory id) {\n if(index == 1) {\n id = \"StarkWare_AllVerifiers_2020_1\";\n } else if (index == 2) {\n id =\"StarkWare_TokensAndRamping_2020_1\";\n } else if (index == 3) {\n id = \"StarkWare_StarkExState_2021_1\";\n } else if(index == 4) {\n id = \"StarkWare_ForcedActions_2020_1\";\n } else if (index == 5) {\n id =\"StarkWare_OnchainVaults_2021_1\";\n } else if (index == 6) {\n id = \"StarkWare_ProxyUtils_2021_1\";\n } else {\nrevert(\"UNEXPECTED_INDEX\");\n }\n }\n\n function initializationSentinel() internal view override {\n string memoryREVERT_MSG = \"INITIALIZATION_BLOCKED\";\n // This initializer sets roots etc. It must not be applied twice.\n // I.e. it can runonly when the state is still empty.\n require(vaultRoot == 0, REVERT_MSG);\n require(vaultTreeHeight == 0, REVERT_MSG);\nrequire(orderRoot == 0, REVERT_MSG);\n require(orderTreeHeight == 0, REVERT_MSG);\n }\n}\n"},"SubContractor.sol":{"content":"/*\nCopyright 2019-2021 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 \"Identity.sol\";\n\ninterfaceSubContractor is Identity {\n function initialize(bytes calldata data) external;\n\n function initializerSize() external view returns(uint256);\n}\n"}}
File 3 of 3: TokensAndRamping
1{"AcceptModifications.sol":{"content":"/*\n Copyright 2019-2021 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 ownerKey,\n uint256 assetType,\n uint256 nonQuantizedAmount,\n uint256quantizedAmount\n );\n\n event LogNftWithdrawalAllowed(uint256 ownerKey, uint256 assetId);\n\n event LogMintableWithdrawalAllowed(uint256ownerKey, uint256 assetId, uint256 quantizedAmount);\n\n /*\n Transfers funds from the on-chain deposit area to the off-chain area.\nImplemented in the Deposits contracts.\n */\n function acceptDeposit(\n uint256 ownerKey,\n uint256 vaultId,\n uint256assetId,\n uint256 quantizedAmount\n ) internal virtual override {\n // Fetch deposit.\n require(\npendingDeposits[ownerKey][assetId][vaultId] \u003e= quantizedAmount,\n \"DEPOSIT_INSUFFICIENT\"\n );\n\n // Subtractaccepted quantized amount.\n pendingDeposits[ownerKey][assetId][vaultId] -= quantizedAmount;\n }\n\n /*\n Transfers funds fromthe off-chain area to the on-chain withdrawal area.\n */\n function allowWithdrawal(\n uint256 ownerKey,\n uint256 assetId,\nuint256 quantizedAmount\n ) internal override {\n // Fetch withdrawal.\n uint256 withdrawal =pendingWithdrawals[ownerKey][assetId];\n\n // Add accepted quantized amount.\n withdrawal += quantizedAmount;\n require(withdrawal \u003e= quantizedAmount, \"WITHDRAWAL_OVERFLOW\");\n\n // Store withdrawal.\n pendingWithdrawals[ownerKey][assetId] =withdrawal;\n\n // Log event.\n uint256 presumedAssetType = assetId;\n if (registeredAssetType[presumedAssetType]) {\nemit LogWithdrawalAllowed(\n ownerKey,\n presumedAssetType,\n fromQuantized(presumedAssetType,quantizedAmount),\n quantizedAmount\n );\n } else if (assetId == ((assetId \u0026 MASK_240) |MINTABLE_ASSET_ID_FLAG)) {\n emit LogMintableWithdrawalAllowed(ownerKey, assetId, quantizedAmount);\n } else {\n //Default case is Non-Mintable ERC721 asset id.\n require(assetId == assetId \u0026 MASK_250, \"INVALID_NFT_ASSET_ID\");\n //In ERC721 case, assetId is not the assetType.\n require(withdrawal \u003c= 1, \"INVALID_NFT_AMOUNT\");\n emitLogNftWithdrawalAllowed(ownerKey, assetId);\n }\n }\n\n // Verifier authorizes withdrawal.\n function acceptWithdrawal(\nuint256 ownerKey,\n uint256 assetId,\n uint256 quantizedAmount\n ) internal virtual override {\n allowWithdrawal(ownerKey,assetId, quantizedAmount);\n }\n}\n"},"ActionHash.sol":{"content":"/*\n Copyright 2019-2021 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\";\n\n/*\n Calculation action hash for the various forcedactions in a generic manner.\n*/\ncontract ActionHash is MainStorage, LibConstants {\n function getActionHash(string memory actionName, bytesmemory packedActionParameters)\n internal\n pure\n returns (bytes32 actionHash)\n {\n actionHash = keccak256(abi.encodePacked(actionName, packedActionParameters));\n }\n\n function setActionHash(bytes32 actionHash, bool premiumCost) internal {\n// The rate of forced trade requests is restricted.\n // First restriction is by capping the number of requests in a block.\n // Usercan override this cap by requesting with a permium flag set,\n // in this case, the gas cost is high (~1M) but no \"technical\" limit is set.\n // However, the high gas cost creates an obvious limitation due to the block gas limit.\n if (premiumCost) {\n for(uint256 i = 0; i \u003c 21129; i++) {}\n } else {\n require(\n forcedRequestsInBlock[block.number] \u003cMAX_FORCED_ACTIONS_REQS_PER_BLOCK,\n \"MAX_REQUESTS_PER_BLOCK_REACHED\"\n );\n forcedRequestsInBlock[block.number] += 1;\n }\n forcedActionRequests[actionHash] = block.timestamp;\n actionHashList.push(actionHash);\n }\n\nfunction getActionCount() external view returns (uint256) {\n return actionHashList.length;\n }\n\n function getActionHashByIndex(uint256 actionIndex) external view returns (bytes32) {\n require(actionIndex \u003c actionHashList.length, \"ACTION_INDEX_TOO_HIGH\");\nreturn actionHashList[actionIndex];\n }\n}\n"},"Common.sol":{"content":"/*\n Copyright 2019-2021 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\n/*\n Common Utility librarries.\n I. Addresses (extending address).\n*/\nlibrary Addresses {\nfunction 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 memorycallData) internal {\n require(isContract(tokenAddress), \"BAD_TOKEN_ADDRESS\");\n // NOLINTNEXTLINE: low-level-calls.\n (boolsuccess, 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 Validates that thepassed contract address is of a real contract,\n and that its id hash (as infered fromn identify()) matched the expected one.\n */\nfunction validateContractId(address contractAddress, bytes32 expectedIdHash) internal {\n require(isContract(contractAddress),\"ADDRESS_NOT_CONTRACT\");\n (bool success, bytes memory returndata) = contractAddress.call( // NOLINT: low-level-calls.\n abi.encodeWithSignature(\"identify()\")\n );\n require(success, \"FAILED_TO_IDENTIFY_CONTRACT\");\n string memory realContractId= abi.decode(returndata, (string));\n require(\n keccak256(abi.encodePacked(realContractId)) == expectedIdHash,\n\"UNEXPECTED_CONTRACT_IDENTIFIER\"\n );\n }\n}\n\n/*\n II. StarkExTypes - Common data types.\n*/\nlibrary StarkExTypes {\n //Structure representing 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 thelist is time-locked, to ensure that any user of the system\n // not content with the announced removal has ample time to leave the system beforeit is\n // removed.\n struct ApprovalChainData {\n address[] list;\n // Represents the time after which the verifier with thegiven address 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"},"CompositeActions.sol":{"content":"/*\n Copyright 2019-2021 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 \"MDeposits.sol\";\n\nabstract contract CompositeActions is MDeposits {\n function registerAndDepositERC20(\n address ethKey,\n uint256 starkKey,\n bytes calldata signature,\n uint256 assetType,\n uint256 vaultId,\nuint256 quantizedAmount\n ) external {\n depositERC20(starkKey, assetType, vaultId, quantizedAmount);\n }\n\n //NOLINTNEXTLINE: locked-ether.\n function registerAndDepositEth(\n address ethKey,\n uint256 starkKey,\n bytes calldatasignature,\n uint256 assetType,\n uint256 vaultId\n ) external payable {\n depositEth(starkKey, assetType, vaultId);\n}\n}\n"},"Deposits.sol":{"content":"/*\n Copyright 2019-2021 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 \"MDeposits.sol\";\nimport \"MTokenQuantization.sol\";\nimport\"MTokenAssetData.sol\";\nimport \"MFreezable.sol\";\nimport \"MKeyGetters.sol\";\nimport \"MTokenTransfers.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 ERC20 contract, authorizing this contractto 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 towhich to send the deposit.\n\n The amount should be quantized, according to the specific quantization defined for the asset type.\n\n The resultof the operation, assuming all requirements are met, is that an amount of ERC20 tokens\n equaling the amount specified in the :sol:func:`deposit`call times the quantization factor is\n transferred on behalf of the user to the contract. In addition, the contract adds the funds to an\naccumulator of pending deposits for the provided user, asset ID and vault ID.\n\n Once a deposit is made, the exchange may include it in a proofwhich will result in addition\n of the amount(s) deposited to the off-chain vault with the specified ID. When the contract\n receives such validproof, it deducts the transfered funds from the pending deposits for the\n specified Stark key, asset ID and vault ID.\n\n The exchange will notbe 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 maycancel the deposit by performing a time-locked cancel-deposit\n operation consisting of two calls:\n\n 1. A call to :sol:func:`depositCancel`,setting a timer to enable reclaiming the deposit. Until this timer expires the user cannot reclaim funds as the exchange may still be processingthe deposit for inclusion in the off chain vault.\n 2. A call to :sol:func:`depositReclaim`, to perform the actual transfer of funds from thecontract 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 ofall funds not accounted for in proofs for off-chain inclusion, back to the user account on the ERC20 contract.\n\n Calling depositCancel anddepositReclaim can only be done via an ethKey that is associated with\n that vault\u0027s starkKey. This is enforced by the contract.\n\n*/\nabstract contract Deposits is\n MainStorage,\n LibConstants,\n MAcceptModifications,\n MDeposits,\n MTokenQuantization,\nMTokenAssetData,\n MFreezable,\n MKeyGetters,\n MTokenTransfers\n{\n event LogDeposit(\n address depositorEthKey,\nuint256 starkKey,\n uint256 vaultId,\n uint256 assetType,\n uint256 nonQuantizedAmount,\n uint256 quantizedAmount\n);\n\n event LogNftDeposit(\n address depositorEthKey,\n uint256 starkKey,\n uint256 vaultId,\n uint256 assetType,\nuint256 tokenId,\n uint256 assetId\n );\n\n event LogDepositCancel(uint256 starkKey, uint256 vaultId, uint256 assetId);\n\nevent LogDepositCancelReclaimed(\n uint256 starkKey,\n uint256 vaultId,\n uint256 assetType,\n uint256nonQuantizedAmount,\n uint256 quantizedAmount\n );\n\n event LogDepositNftCancelReclaimed(\n uint256 starkKey,\n uint256vaultId,\n uint256 assetType,\n uint256 tokenId,\n uint256 assetId\n );\n\n function getDepositBalance(\n uint256starkKey,\n uint256 assetId,\n uint256 vaultId\n ) external view returns (uint256 balance) {\n uint256 presumedAssetType =assetId;\n balance = fromQuantized(presumedAssetType, pendingDeposits[starkKey][assetId][vaultId]);\n }\n\n functiongetQuantizedDepositBalance(\n uint256 starkKey,\n uint256 assetId,\n uint256 vaultId\n ) external view returns (uint256balance) {\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 // The vaultId is not validated butshould be in the allowed range supported by the\n // exchange. If not, it will be ignored by the exchange and the starkKey owner mayreclaim\n // the funds by using depositCancel + depositReclaim.\n\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.\n pendingDeposits[starkKey][assetId][vaultId] = 1;\n\n // Disable the cancellationRequesttimeout when users deposit into their own account.\n if (\n isMsgSenderKeyOwner(starkKey) \u0026\u0026cancellationRequests[starkKey][assetId][vaultId] != 0\n ) {\n delete cancellationRequests[starkKey][assetId][vaultId];\n}\n\n // Transfer the tokens to the Deposit contract.\n transferInNft(assetType, tokenId);\n\n // Log event.\n emitLogNftDeposit(msg.sender, starkKey, vaultId, assetType, tokenId, assetId);\n }\n\n function getCancellationRequest(\n uint256 starkKey,\n uint256 assetId,\n uint256 vaultId\n ) external view returns (uint256 request) {\n request =cancellationRequests[starkKey][assetId][vaultId];\n }\n\n function depositERC20(\n uint256 starkKey,\n uint256 assetType,\nuint256 vaultId,\n uint256 quantizedAmount\n ) public override {\n deposit(starkKey, assetType, vaultId, quantizedAmount);\n}\n\n // NOLINTNEXTLINE: locked-ether.\n function depositEth(\n uint256 starkKey,\n uint256 assetType,\n uint256vaultId\n ) public payable override {\n require(isEther(assetType), \"INVALID_ASSET_TYPE\");\n deposit(starkKey, assetType,vaultId, toQuantized(assetType, msg.value));\n }\n\n function deposit(\n uint256 starkKey,\n uint256 assetType,\nuint256 vaultId,\n uint256 quantizedAmount\n ) public notFrozen {\n // The vaultId is not validated but should be in the allowedrange supported by the\n // exchange. If not, it will be ignored by the exchange and the starkKey owner may reclaim\n // the funds byusing depositCancel + depositReclaim.\n\n // No need to verify amount \u003e 0, a deposit with amount = 0 can be used to undo cancellation.\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(pendingDeposits[starkKey][assetId][vaultId] \u003e=quantizedAmount, \"DEPOSIT_OVERFLOW\");\n\n // Disable the cancellationRequest timeout when users deposit into their own account.\nif (\n isMsgSenderKeyOwner(starkKey) \u0026\u0026 cancellationRequests[starkKey][assetId][vaultId] != 0\n ) {\n deletecancellationRequests[starkKey][assetId][vaultId];\n }\n\n // Transfer the tokens to the Deposit contract.\n transferIn(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\nfunction deposit(\n // 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 onlyKeyOwner(starkKey)\n // No notFrozen modifier: This function can always be used, even when frozen.\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 onlyKeyOwner(starkKey)\n // No notFrozen modifier: This function can always be used, even whenfrozen.\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 onlyKeyOwner(starkKey)\n// No notFrozen modifier: This function can always be used, even when frozen.\n {\n // assetId is the id for the deposits/withdrawals.\n // equivalent for the usage of assetType for ERC20.\n uint256 assetId = calculateNftAssetId(assetType, tokenId);\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\");\n\n // Clear deposit.\n uint256 amount =pendingDeposits[starkKey][assetId][vaultId];\n delete pendingDeposits[starkKey][assetId][vaultId];\n deletecancellationRequests[starkKey][assetId][vaultId];\n\n if (amount \u003e 0) {\n // Refund deposit.\n transferOutNft(msg.sender, assetType, tokenId);\n\n // Log event.\n emit LogDepositNftCancelReclaimed(starkKey, vaultId, assetType, tokenId,assetId);\n }\n }\n}\n"},"ECDSA.sol":{"content":"/*\n Copyright 2019-2021 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 \"EllipticCurve.sol\";\n\nlibrary ECDSA {\n using EllipticCurve for uint256;\n uint256 constant FIELD_PRIME =\n0x800000000000011000000000000000000000000000000000000000000000001;\n uint256 constant ALPHA = 1;\n uint256 constant BETA =\n3141592653589793238462643383279502884197169399375105820974944592307816406665;\n uint256 constant EC_ORDER =\n3618502788666131213697322783095070105526743751716087489154079457884512865583;\n uint256 constant N_ELEMENT_BITS_ECDSA = 251;\n uint256constant EC_GEN_X = 0x1ef15c18599971b7beced415a40f0c7deacfd9b0d1819e03d723d8bc943cfca;\n uint256 constant EC_GEN_Y =0x5668060aa49730b7be4801df46ec62de53ecd11abe43a32873000c36e8dc1f;\n\n function verify(\n uint256 msgHash,\n uint256 r,\nuint256 s,\n uint256 pubX,\n uint256 pubY\n ) internal pure {\n require(msgHash % EC_ORDER == msgHash, \"msgHash out ofrange\");\n require((1 \u003c= s) \u0026\u0026 (s \u003c EC_ORDER), \"s out of range\");\n uint256 w = s.invMod(EC_ORDER);\nrequire((1 \u003c= r) \u0026\u0026 (r \u003c (1 \u003c\u003c N_ELEMENT_BITS_ECDSA)), \"r out of range\");\n require((1 \u003c= w)\u0026\u0026 (w \u003c (1 \u003c\u003c N_ELEMENT_BITS_ECDSA)), \"w out of range\");\n\n // Verify that pub is a valid point (y^2 = x^3 + x +BETA).\n {\n uint256 x3 = mulmod(mulmod(pubX, pubX, FIELD_PRIME), pubX, FIELD_PRIME);\n uint256 y2 = mulmod(pubY, pubY, FIELD_PRIME);\n require(\n y2 == addmod(addmod(x3, pubX, FIELD_PRIME), BETA, FIELD_PRIME),\n\"INVALID_STARK_KEY\"\n );\n }\n\n // Verify signature.\n uint256 b_x;\n uint256 b_y;\n {\n(uint256 zG_x, uint256 zG_y) = msgHash.ecMul(EC_GEN_X, EC_GEN_Y, ALPHA, FIELD_PRIME);\n\n (uint256 rQ_x, uint256 rQ_y) = r.ecMul(pubX,pubY, ALPHA, FIELD_PRIME);\n\n (b_x, b_y) = zG_x.ecAdd(zG_y, rQ_x, rQ_y, ALPHA, FIELD_PRIME);\n }\n (uint256 res_x, ) = w.ecMul(b_x, b_y, ALPHA, FIELD_PRIME);\n\n require(res_x == r, \"INVALID_STARK_SIGNATURE\");\n }\n}\n"},"EllipticCurve.sol":{"content":"/*\n Copyright 2019-2021 StarkWare Industries Ltd.\n\n Licensed under the Apache License, Version 2.0 (the \"License\").\n You may not use thisfile 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\nUnless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES 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: MIT.\n/*\n MIT License\n\n Copyright (c) 2019 Witnet Project\n\n Permission ishereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWAREIS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OROTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OROTHER DEALINGS IN THE\n SOFTWARE.\n*/\n// https://github.com/witnet/elliptic-curve-solidity/blob/master/contracts/EllipticCurve.sol\npragmasolidity \u003e=0.5.3 \u003c0.7.0; // NOLINT pragma.\n\n/**\n * @title Elliptic Curve Library\n * @dev Library providing arithmetic operations overelliptic curves.\n * This library does not check whether the inserted points belong to the curve\n * `isOnCurve` function should be used by thelibrary user to check the aforementioned statement.\n * @author Witnet Foundation\n */\nlibrary EllipticCurve {\n\n // Pre-computed constant for 2** 255\n uint256 constant private U255_MAX_PLUS_1 = 57896044618658097711785492504343953926634992332820282019728792003956564819968;\n\n /// @devModular euclidean inverse of a number (mod p).\n /// @param _x The number\n /// @param _pp The modulus\n /// @return q such that x*q = 1 (mod_pp)\n function invMod(uint256 _x, uint256 _pp) internal pure returns (uint256) {\n require(_x != 0 \u0026\u0026 _x != _pp \u0026\u0026 _pp !=0, \"Invalid number\");\n uint256 q = 0;\n uint256 newT = 1;\n uint256 r = _pp;\n uint256 t;\n while (_x != 0) {\n t = r / _x;\n (q, newT) = (newT, addmod(q, (_pp - mulmod(t, newT, _pp)), _pp));\n (r, _x) = (_x, r - t * _x);\n }\n\n return q;\n }\n\n ///@dev Modular exponentiation, b^e % _pp.\n /// Source: https://github.com/androlo/standard-contracts/blob/master/contracts/src/crypto/ECCMath.sol\n/// @param _base base\n /// @param _exp exponent\n /// @param _pp modulus\n /// @return r such that r = b**e (mod _pp)\n function expMod(uint256 _base, uint256 _exp, uint256 _pp) internal pure returns (uint256) {\n require(_pp!=0, \"Modulus is zero\");\n\n if (_base == 0)\nreturn 0;\n if (_exp == 0)\n return 1;\n\n uint256 r = 1;\n uint256 bit = U255_MAX_PLUS_1;\n assembly {\n for { } gt(bit,0) { }{\n r := mulmod(mulmod(r, r, _pp), exp(_base, iszero(iszero(and(_exp, bit)))), _pp)\n r := mulmod(mulmod(r, r, _pp), exp(_base,iszero(iszero(and(_exp, div(bit, 2))))), _pp)\n r := mulmod(mulmod(r, r, _pp), exp(_base, iszero(iszero(and(_exp, div(bit, 4))))), _pp)\nr := mulmod(mulmod(r, r, _pp), exp(_base, iszero(iszero(and(_exp, div(bit, 8))))), _pp)\n bit := div(bit, 16)\n }\n }\n\nreturn r;\n }\n\n /// @dev Converts a point (x, y, z) expressed in Jacobian coordinates to affine coordinates (x\u0027, y\u0027, 1).\n ///@param _x coordinate x\n /// @param _y coordinate y\n /// @param _z coordinate z\n /// @param _pp the modulus\n /// @return (x\u0027, y\u0027)affine coordinates\n function toAffine(\n uint256 _x,\n uint256 _y,\n uint256 _z,\n uint256 _pp)\n internal pure returns (uint256,uint256)\n {\n uint256 zInv = invMod(_z, _pp);\n uint256 zInv2 = mulmod(zInv, zInv, _pp);\n uint256 x2 = mulmod(_x, zInv2, _pp);\nuint256 y2 = mulmod(_y, mulmod(zInv, zInv2, _pp), _pp);\n\n return (x2, y2);\n }\n\n /// @dev Derives the y coordinate from a compressed-format point x [[SEC-1]](https://www.secg.org/SEC1-Ver-1.0.pdf).\n /// @param _prefix parity byte (0x02 even, 0x03 odd)\n /// @param _xcoordinate x\n /// @param _aa constant of curve\n /// @param _bb constant of curve\n /// @param _pp the modulus\n /// @return y coordinate y\nfunction deriveY(\n uint8 _prefix,\n uint256 _x,\n uint256 _aa,\n uint256 _bb,\n uint256 _pp)\n internal pure returns (uint256)\n{\n require(_prefix == 0x02 || _prefix == 0x03, \"Invalid compressed EC point prefix\");\n\n // x^3 + ax + b\n uint256 y2 = addmod(mulmod(_x, mulmod(_x, _x, _pp), _pp), addmod(mulmod(_x, _aa, _pp), _bb, _pp), _pp);\n y2 = expMod(y2, (_pp + 1) / 4, _pp);\n // uint256 cmp = yBit^ y_ \u0026 1;\n uint256 y = (y2 + _prefix) % 2 == 0 ? y2 : _pp - y2;\n\n return y;\n }\n\n /// @dev Check whether point (x,y) is on curvedefined by a, b, and _pp.\n /// @param _x coordinate x of P1\n /// @param _y coordinate y of P1\n /// @param _aa constant of curve\n /// @param_bb constant of curve\n /// @param _pp the modulus\n /// @return true if x,y in the curve, false else\n function isOnCurve(\n uint _x,\nuint _y,\n uint _aa,\n uint _bb,\n uint _pp)\n internal pure returns (bool)\n {\n if (0 == _x || _x \u003e= _pp || 0 == _y || _y\u003e= _pp) {\n return false;\n }\n // y^2\n uint lhs = mulmod(_y, _y, _pp);\n // x^3\n uint rhs = mulmod(mulmod(_x, _x, _pp),_x, _pp);\n if (_aa != 0) {\n // x^3 + a*x\n rhs = addmod(rhs, mulmod(_x, _aa, _pp), _pp);\n }\n if (_bb != 0) {\n // x^3 +a*x + b\n rhs = addmod(rhs, _bb, _pp);\n }\n\n return lhs == rhs;\n }\n\n /// @dev Calculate inverse (x, -y) of point (x, y).\n ///@param _x coordinate x of P1\n /// @param _y coordinate y of P1\n /// @param _pp the modulus\n /// @return (x, -y)\n function ecInv(\nuint256 _x,\n uint256 _y,\n uint256 _pp)\n internal pure returns (uint256, uint256)\n {\n return (_x, (_pp - _y) % _pp);\n }\n\n ///@dev Add two points (x1, y1) and (x2, y2) in affine coordinates.\n /// @param _x1 coordinate x of P1\n /// @param _y1 coordinate y of P1\n ///@param _x2 coordinate x of P2\n /// @param _y2 coordinate y of P2\n /// @param _aa constant of the curve\n /// @param _pp the modulus\n ///@return (qx, qy) = P1+P2 in affine coordinates\n function ecAdd(\n uint256 _x1,\n uint256 _y1,\n uint256 _x2,\n uint256 _y2,\nuint256 _aa,\n uint256 _pp)\n internal pure returns(uint256, uint256)\n {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n\n //Double if x1==x2 else add\n if (_x1==_x2) {\n // y1 = -y2 mod p\n if (addmod(_y1, _y2, _pp) == 0) {\n return(0, 0);\n }else {\n // P1 = P2\n (x, y, z) = jacDouble(\n _x1,\n _y1,\n 1,\n _aa,\n _pp);\n}\n } else {\n (x, y, z) = jacAdd(\n _x1,\n _y1,\n 1,\n _x2,\n _y2,\n 1,\n _pp);\n }\n// Get back to affine\n return toAffine(\n x,\n y,\n z,\n _pp);\n }\n\n /// @dev Substract two points (x1, y1) and (x2,y2) in affine coordinates.\n /// @param _x1 coordinate x of P1\n /// @param _y1 coordinate y of P1\n /// @param _x2 coordinate x of P2\n ///@param _y2 coordinate y of P2\n /// @param _aa constant of the curve\n /// @param _pp the modulus\n /// @return (qx, qy) = P1-P2 in affinecoordinates\n function ecSub(\n uint256 _x1,\n uint256 _y1,\n uint256 _x2,\n uint256 _y2,\n uint256 _aa,\n uint256 _pp)\ninternal pure returns(uint256, uint256)\n {\n // invert square\n (uint256 x, uint256 y) = ecInv(_x2, _y2, _pp);\n // P1-square\nreturn ecAdd(\n _x1,\n _y1,\n x,\n y,\n _aa,\n _pp);\n }\n\n /// @dev Multiply point (x1, y1, z1) times d in affinecoordinates.\n /// @param _k scalar to multiply\n /// @param _x coordinate x of P1\n /// @param _y coordinate y of P1\n /// @param _aa constantof the curve\n /// @param _pp the modulus\n /// @return (qx, qy) = d*P in affine coordinates\n function ecMul(\n uint256 _k,\n uint256 _x,\n uint256 _y,\n uint256 _aa,\n uint256 _pp)\n internal pure returns(uint256, uint256)\n {\n // Jacobian multiplication\n(uint256 x1, uint256 y1, uint256 z1) = jacMul(\n _k,\n _x,\n _y,\n 1,\n _aa,\n _pp);\n // Get back to affine\nreturn toAffine(\n x1,\n y1,\n z1,\n _pp);\n }\n\n /// @dev Adds two points (x1, y1, z1) and (x2 y2, z2).\n /// @param _x1coordinate x of P1\n /// @param _y1 coordinate y of P1\n /// @param _z1 coordinate z of P1\n /// @param _x2 coordinate x of square\n /// @param_y2 coordinate y of square\n /// @param _z2 coordinate z of square\n /// @param _pp the modulus\n /// @return (qx, qy, qz) P1+square inJacobian\n function jacAdd(\n uint256 _x1,\n uint256 _y1,\n uint256 _z1,\n uint256 _x2,\n uint256 _y2,\n uint256 _z2,\nuint256 _pp)\n internal pure returns (uint256, uint256, uint256)\n {\n if (_x1==0 \u0026\u0026 _y1==0)\n return (_x2, _y2, _z2);\n if(_x2==0 \u0026\u0026 _y2==0)\n return (_x1, _y1, _z1);\n\n // We follow the equations described in https://pdfs.semanticscholar.org/5c64/29952e08025a9649c2b0ba32518e9a7fb5c2.pdf Section 5\n uint[4] memory zs; // z1^2, z1^3, z2^2, z2^3\n zs[0] = mulmod(_z1, _z1, _pp);\nzs[1] = mulmod(_z1, zs[0], _pp);\n zs[2] = mulmod(_z2, _z2, _pp);\n zs[3] = mulmod(_z2, zs[2], _pp);\n\n // u1, s1, u2, s2\n zs = [\nmulmod(_x1, zs[2], _pp),\n mulmod(_y1, zs[3], _pp),\n mulmod(_x2, zs[0], _pp),\n mulmod(_y2, zs[1], _pp)\n ];\n\n // Incase of zs[0] == zs[2] \u0026\u0026 zs[1] == zs[3], double function should be used\n require(zs[0] != zs[2] || zs[1] != zs[3], \"Use jacDoublefunction instead\");\n\n uint[4] memory hr;\n //h\n hr[0] = addmod(zs[2], _pp - zs[0], _pp);\n //r\n hr[1] = addmod(zs[3], _pp -zs[1], _pp);\n //h^2\n hr[2] = mulmod(hr[0], hr[0], _pp);\n // h^3\n hr[3] = mulmod(hr[2], hr[0], _pp);\n // qx = -h^3 -2u1h^2+r^2\n uint256 qx = addmod(mulmod(hr[1], hr[1], _pp), _pp - hr[3], _pp);\n qx = addmod(qx, _pp - mulmod(2, mulmod(zs[0], hr[2], _pp), _pp),_pp);\n // qy = -s1*z1*h^3+r(u1*h^2 -x^3)\n uint256 qy = mulmod(hr[1], addmod(mulmod(zs[0], hr[2], _pp), _pp - qx, _pp), _pp);\n qy =addmod(qy, _pp - mulmod(zs[1], hr[3], _pp), _pp);\n // qz = h*z1*z2\n uint256 qz = mulmod(hr[0], mulmod(_z1, _z2, _pp), _pp);\n return(qx,qy, qz);\n }\n\n /// @dev Doubles a points (x, y, z).\n /// @param _x coordinate x of P1\n /// @param _y coordinate y of P1\n /// @param _zcoordinate z of P1\n /// @param _aa the a scalar in the curve equation\n /// @param _pp the modulus\n /// @return (qx, qy, qz) 2P in Jacobian\nfunction jacDouble(\n uint256 _x,\n uint256 _y,\n uint256 _z,\n uint256 _aa,\n uint256 _pp)\n internal pure returns (uint256,uint256, uint256)\n {\n if (_z == 0)\n return (_x, _y, _z);\n\n // We follow the equations described in https://pdfs.semanticscholar.org/5c64/29952e08025a9649c2b0ba32518e9a7fb5c2.pdf Section 5\n // Note: there is a bug in the paper regarding the m parameter, M=3*(x1^2)+a*(z1^4)\n // x, y, z at this point represent the squares of _x, _y, _z\n uint256 x = mulmod(_x, _x, _pp); //x1^2\n uint256 y = mulmod(_y,_y, _pp); //y1^2\n uint256 z = mulmod(_z, _z, _pp); //z1^2\n\n // s\n uint s = mulmod(4, mulmod(_x, y, _pp), _pp);\n // m\n uint m =addmod(mulmod(3, x, _pp), mulmod(_aa, mulmod(z, z, _pp), _pp), _pp);\n\n // x, y, z at this point will be reassigned and rather represent qx, qy, qz from the paper\n // This allows to reduce the gas cost and stack footprint of the algorithm\n // qx\n x = addmod(mulmod(m, m, _pp),_pp - addmod(s, s, _pp), _pp);\n // qy = -8*y1^4 + M(S-T)\n y = addmod(mulmod(m, addmod(s, _pp - x, _pp), _pp), _pp - mulmod(8, mulmod(y, y,_pp), _pp), _pp);\n // qz = 2*y1*z1\n z = mulmod(2, mulmod(_y, _z, _pp), _pp);\n\n return (x, y, z);\n }\n\n /// @dev Multiply point (x,y, z) times d.\n /// @param _d scalar to multiply\n /// @param _x coordinate x of P1\n /// @param _y coordinate y of P1\n /// @param _zcoordinate z of P1\n /// @param _aa constant of curve\n /// @param _pp the modulus\n /// @return (qx, qy, qz) d*P1 in Jacobian\n functionjacMul(\n uint256 _d,\n uint256 _x,\n uint256 _y,\n uint256 _z,\n uint256 _aa,\n uint256 _pp)\n internal pure returns (uint256,uint256, uint256)\n {\n // Early return in case that `_d == 0`\n if (_d == 0) {\n return (_x, _y, _z);\n }\n\n uint256 remaining= _d;\n uint256 qx = 0;\n uint256 qy = 0;\n uint256 qz = 1;\n\n // Double and add algorithm\n while (remaining != 0) {\n if((remaining \u0026 1) != 0) {\n (qx, qy, qz) = jacAdd(\n qx,\n qy,\n qz,\n _x,\n _y,\n_z,\n _pp);\n }\n remaining = remaining / 2;\n (_x, _y, _z) = jacDouble(\n _x,\n _y,\n _z,\n_aa,\n _pp);\n }\n return (qx, qy, qz);\n }\n}\n"},"ERC721Receiver.sol":{"content":"/*\n Copyright 2019-2021 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 \"IERC721Receiver.sol\";\n\n/*\n ERC721 token receiver interface\n EIP-721 requiresany contract receiving ERC721 tokens to implement IERC721Receiver interface.\n By EIP, safeTransferFrom API of ERC721 shall call onERC721Receivedon the receiving contract.\n\n Have the receiving contract failed to respond as expected, the safeTransferFrom shall be reverted.\n\n Params:\n`operator` The address which called `safeTransferFrom` function\n `from` The address which previously owned the token\n `tokenId` The NFTidentifier which is being transferred\n `data` Additional data with no specified format\n\n Returns: fixed value:`bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`.\n*/\ncontract ERC721Receiver is IERC721Receiver {\n function onERC721Received(\naddress, // operator - The address which called `safeTransferFrom` function.\n address, // from - The address which previously owned thetoken.\n uint256, // tokenId - The NFT identifier which is being transferred.\n bytes memory // data - Additional data with nospecified format.\n ) external override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n}\n"},"Freezable.sol":{"content":"/*\n Copyright 2019-2021 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 \"LibConstants.sol\";\nimport \"MFreezable.sol\";\nimport \"MGovernance.sol\";\nimport \"MainStorage.sol\";\n\n/*\n Implements MFreezable.\n*/\nabstractcontract Freezable is MainStorage, LibConstants, MGovernance, MFreezable {\n event LogFrozen();\n event LogUnFrozen();\n\n functionisFrozen() public view override returns (bool) {\n return stateFrozen;\n }\n\n function validateFreezeRequest(uint256 requestTime)internal override {\n require(requestTime != 0, \"FORCED_ACTION_UNREQUESTED\");\n // Verify timer on escape request.\n uint256freezeTime = requestTime + FREEZE_GRACE_PERIOD;\n\n // Prevent wraparound.\n assert(freezeTime \u003e= FREEZE_GRACE_PERIOD);\nrequire(block.timestamp \u003e= freezeTime, \"FORCED_ACTION_PENDING\"); // NOLINT: timestamp.\n\n // Forced action requests placed beforefreeze, are no longer valid after the un-freeze.\n require(freezeTime \u003e unFreezeTime, \"REFREEZE_ATTEMPT\");\n }\n\n functionfreeze() internal override notFrozen {\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() external onlyFrozen onlyGovernance {\n require(block.timestamp \u003e= unFreezeTime, \"UNFREEZE_NOT_ALLOWED_YET\");\n\n // Update state.\n stateFrozen = false;\n\n //Increment roots to invalidate them, w/o losing information.\n vaultRoot += 1;\n orderRoot += 1;\n\n // Log event.\nemit LogUnFrozen();\n }\n}\n"},"Governance.sol":{"content":"/*\n Copyright 2019-2021 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 \"GovernanceStorage.sol\";\nimport \"MGovernance.sol\";\n\n/*\n Implements Generic Governance, applicable for both proxy andmain contract, and possibly others.\n Notes:\n 1. This class is virtual (getGovernanceTag is not implemented).\n 2. The use of the same functionnames by both the Proxy and a delegated implementation\n is not possible since calling the implementation functions is done via the defaultfunction\n of the Proxy. For this reason, for example, the implementation of MainContract (MainGovernance)\n exposes mainIsGovernor, whichcalls the internal isGovernor method.\n*/\nabstract contract Governance is GovernanceStorage, MGovernance {\n event LogNominatedGovernor(addressnominatedGovernor);\n event LogNewGovernorAccepted(address acceptedGovernor);\n event LogRemovedGovernor(address removedGovernor);\n eventLogNominationCancelled();\n\n /*\n Returns a string which uniquely identifies the type of the governance mechanism.\n */\n functiongetGovernanceTag() internal pure virtual returns (string memory);\n\n /*\n Returns the GovernanceInfoStruct associated with the governancetag.\n */\n function contractGovernanceInfo() internal view returns (GovernanceInfoStruct storage) {\n string memory tag =getGovernanceTag();\n GovernanceInfoStruct storage gub = governanceInfo[tag];\n require(gub.initialized, \"NOT_INITIALIZED\");\nreturn gub;\n }\n\n /*\n Current code intentionally prevents governance re-initialization.\n This may be a problem in an upgradesituation, in a case that the upgrade-to implementation\n performs an initialization (for real) and within that calls initGovernance().\n\nPossible workarounds:\n 1. Clearing the governance info altogether by changing the MAIN_GOVERNANCE_INFO_TAG.\n This will removeexisting 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 lines below).\n */\n function initGovernance() internal {\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 functionisGovernor(address testGovernor) internal view override returns (bool) {\n GovernanceInfoStruct storage gub = contractGovernanceInfo();\nreturn gub.effectiveGovernors[testGovernor];\n }\n\n /*\n Cancels the nomination of a governor candidate.\n */\n functioncancelNomination() internal onlyGovernance {\n GovernanceInfoStruct storage gub = contractGovernanceInfo();\n gub.candidateGovernor =address(0x0);\n emit LogNominationCancelled();\n }\n\n function nominateNewGovernor(address newGovernor) internal onlyGovernance {\nGovernanceInfoStruct storage gub = contractGovernanceInfo();\n require(!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 Thedifference is that the init path skips the nominate step\n that would fail because of the onlyGovernance modifier.\n */\n functionaddGovernor(address newGovernor) private {\n require(!isGovernor(newGovernor), \"ALREADY_GOVERNOR\");\n GovernanceInfoStruct storagegub = contractGovernanceInfo();\n gub.effectiveGovernors[newGovernor] = true;\n }\n\n function acceptGovernance() internal {\n// The new governor was proposed as a candidate by the current governor.\n GovernanceInfoStruct storage gub = contractGovernanceInfo();\nrequire(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 emitLogNewGovernorAccepted(msg.sender);\n }\n\n /*\n Remove a governor from office.\n */\n function removeGovernor(addressgovernorForRemoval) internal onlyGovernance {\n require(msg.sender != governorForRemoval, \"GOVERNOR_SELF_REMOVE\");\nGovernanceInfoStruct 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-2021 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 Holds thegovernance slots for ALL entities, including proxy and the main contract.\n*/\ncontract GovernanceStorage {\n struct GovernanceInfoStruct {\nmapping(address =\u003e bool) effectiveGovernors;\n address candidateGovernor;\n bool initialized;\n }\n\n // A map from aGovernor tag to its own GovernanceInfoStruct.\n mapping(string =\u003e GovernanceInfoStruct) internal governanceInfo;\n}\n"},"Identity.sol":{"content":"/*\n Copyright 2019-2021 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\ninterface Identity {\n/*\n Allows a caller, typically another contract,\n to ensure that the provided address is of the expected type and version.\n */\nfunction identify() external pure returns (string memory);\n}\n"},"IERC20.sol":{"content":"/*\n Copyright 2019-2021 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 Interface of the ERC20 standard as defined in the EIP. Does not include\n the optionalfunctions; to access them see {ERC20Detailed}.\n*/\ninterface IERC20 {\n function totalSupply() external view returns (uint256);\n\n functionbalanceOf(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, uint256amount) external returns (bool);\n\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n )external returns (bool);\n\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n event Approval(address indexedowner, address indexed spender, uint256 value);\n}\n"},"IERC721Receiver.sol":{"content":"/*\n Copyright 2019-2021 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 IERC721Receiver {\n function onERC721Received(\n address operator,\naddress from,\n uint256 tokenId,\n bytes memory data\n ) external returns (bytes4);\n}\n"},"KeyGetters.sol":{"content":"/*\nCopyright 2019-2021 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\"MKeyGetters.sol\";\n\n/*\n Implements MKeyGetters.\n*/\ncontract KeyGetters is MainStorage, MKeyGetters {\n uint256 internal constantMASK_ADDRESS = (1 \u003c\u003c 160) - 1;\n\n /*\n Returns the Ethereum public key (address) that owns the given ownerKey.\n If theownerKey size is within the range of an Ethereum address (i.e. \u003c 2**160)\n it returns the owner key itself.\n\n If the ownerKey islarger than a potential eth address, the eth address for which the starkKey\n was registered is returned, and 0 if the starkKey is notregistered.\n\n Note - prior to version 4.0 this function reverted on an unregistered starkKey.\n For a variant of this function thatreverts on an unregistered starkKey, use strictGetEthKey.\n */\n function getEthKey(uint256 ownerKey) public view override returns (address){\n address registeredEth = ethKeys[ownerKey];\n\n if (registeredEth != address(0x0)) {\n return registeredEth;\n}\n\n return ownerKey == (ownerKey \u0026 MASK_ADDRESS) ? address(ownerKey) : address(0x0);\n }\n\n /*\n Same as getEthKey, butfails when a stark key is not registered.\n */\n function strictGetEthKey(uint256 ownerKey) internal view override returns (address ethKey){\n ethKey = getEthKey(ownerKey);\n require(ethKey != address(0x0), \"USER_UNREGISTERED\");\n }\n\n functionisMsgSenderKeyOwner(uint256 ownerKey) internal view override returns (bool) {\n return msg.sender == getEthKey(ownerKey);\n }\n}\n"},"LibConstants.sol":{"content":"/*\n Copyright 2019-2021 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\ncontract LibConstants {\n // Durations for time locked mechanisms (in seconds).\n // Note that it is known that miners can manipulateblock timestamps\n // up to a deviation of a few seconds.\n // This mechanism should not be used for fine grained timing.\n\n // The timerequired to cancel a deposit, in the case the operator does not move the funds\n // to the off-chain storage.\n uint256 public constantDEPOSIT_CANCEL_DELAY = 2 days;\n\n // The time required to freeze the exchange, in the case the operator does not execute a\n // requestedfull withdrawal.\n uint256 public constant FREEZE_GRACE_PERIOD = 7 days;\n\n // The time after which the exchange may be unfrozen after itfroze. This should be enough time\n // for users to perform escape hatches to get back their funds.\n uint256 public constant UNFREEZE_DELAY= 365 days;\n\n // Maximal number of verifiers which may co-exist.\n uint256 public constant MAX_VERIFIER_COUNT = uint256(64);\n\n // Thetime required to remove a verifier in case of a verifier upgrade.\n uint256 public constant VERIFIER_REMOVAL_DELAY = FREEZE_GRACE_PERIOD + (21days);\n\n address constant ZERO_ADDRESS = address(0x0);\n\n uint256 constant K_MODULUS =0x800000000000011000000000000000000000000000000000000000000000001;\n\n uint256 constant K_BETA =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\nuint256 constant QUANTUM_UPPER_BOUND = 2**128;\n uint256 internal constant MINTABLE_ASSET_ID_FLAG = 1 \u003c\u003c 250;\n}\n"},"MAcceptModifications.sol":{"content":"/*\n Copyright 2019-2021 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\n/*\nInterface containing actions a verifier can invoke on the state.\n The contract containing the state should implement these and verifycorrectness.\n*/\nabstract contract MAcceptModifications {\n function acceptDeposit(\n uint256 ownerKey,\n uint256 vaultId,\nuint256 assetId,\n uint256 quantizedAmount\n ) internal virtual;\n\n function allowWithdrawal(\n uint256 ownerKey,\nuint256 assetId,\n uint256 quantizedAmount\n ) internal virtual;\n\n function acceptWithdrawal(\n uint256 ownerKey,\nuint256 assetId,\n uint256 quantizedAmount\n ) internal virtual;\n}\n"},"MainGovernance.sol":{"content":"/*\n Copyright 2019-2021StarkWare 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 \"Governance.sol\";\n\n/**\n The StarkEx contract is governed by oneor more Governors of which the initial one is the\n deployer of the contract.\n\n A governor has the sole authority to perform the followingoperations:\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:`TokenRegister`)\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\nThis two step procedure ensures that a governor public key cannot be nominated unless there is an\n entity that has the corresponding private key.This is 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/*\n Implements Governance for the StarkDex main contract.\n The wrapper methods (e.g. mainIsGovernor wrapping isGovernor) are needed togive\n the method unique names.\n Both Proxy and StarkExchange inherit from Governance. Thus, the logical contract method names\n must haveunique names in order for the proxy to successfully delegate to them.\n*/\ncontract MainGovernance is Governance {\n // The tag is the sting keythat is used in the Governance storage mapping.\n string public constant MAIN_GOVERNANCE_INFO_TAG = \"StarkEx.Main.2019.GovernorsInformation\";\n\n function getGovernanceTag() internal pure override returns (string memory tag) {\n tag = MAIN_GOVERNANCE_INFO_TAG;\n }\n\nfunction mainIsGovernor(address testGovernor) external view returns (bool) {\n return isGovernor(testGovernor);\n }\n\n functionmainNominateNewGovernor(address newGovernor) external {\n nominateNewGovernor(newGovernor);\n }\n\n function mainRemoveGovernor(address governorForRemoval) external {\n removeGovernor(governorForRemoval);\n }\n\n function mainAcceptGovernance() external {\nacceptGovernance();\n }\n\n function mainCancelNomination() external {\n cancelNomination();\n }\n}\n"},"MainStorage.sol":{"content":"/*\n Copyright 2019-2021 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 \"ProxyStorage.sol\";\nimport \"Common.sol\";\n\n/*\n Holds ALL the main contract state (storage) variables.\n*/\ncontract MainStorage is ProxyStorage {\nuint256 internal constant LAYOUT_LENGTH = 2**64;\n\n address escapeVerifierAddress; // NOLINT: constable-states.\n\n // Global dex-frozenflag.\n bool stateFrozen; // NOLINT: constable-states.\n\n // Time when unFreeze can be successfully called (UNFREEZE_DELAY after freeze).\nuint256 unFreezeTime; // NOLINT: constable-states.\n\n // Pending deposits.\n // A map STARK key =\u003e asset id =\u003e vault id =\u003equantized amount.\n mapping(uint256 =\u003e mapping(uint256 =\u003e mapping(uint256 =\u003e uint256))) pendingDeposits;\n\n // Cancellationrequests.\n // A map STARK key =\u003e asset id =\u003e vault id =\u003e request timestamp.\n mapping(uint256 =\u003e mapping(uint256 =\u003emapping(uint256 =\u003e uint256))) cancellationRequests;\n\n // Pending withdrawals.\n // A map STARK key =\u003e asset id =\u003e quantizedamount.\n mapping(uint256 =\u003e mapping(uint256 =\u003e uint256)) pendingWithdrawals;\n\n // vault_id =\u003e escape used boolean.\nmapping(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 // NOLINTNEXTLINE naming-convention.\n mapping(uint256 =\u003e mapping(uint256 =\u003e uint256)) fullWithdrawalRequests_DEPRECATED;\n\n // State sequence number.\nuint256 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-states uninitialized-state.\n\n // Order TreeRoot \u0026 Height.\n uint256 orderRoot; // NOLINT: constable-states uninitialized-state.\n uint256 orderTreeHeight; // NOLINT: constable-states uninitialized-state.\n\n // True if and only if the address is allowed to add tokens.\n mapping(address =\u003e bool) tokenAdmins;\n\n // This mapping is no longer in use, remains for backwards compatibility.\n mapping(address =\u003e bool) userAdmins_DEPRECATED; //NOLINT: naming-convention.\n\n // True if and only if the address is an operator (allowed to update state).\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 // Thismapping is no longer in use, remains for backwards compatibility.\n mapping(address =\u003e uint256) starkKeys_DEPRECATED; // NOLINT: naming-convention.\n\n // Mapping from STARK public 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.ApprovalChainDataverifiersChain;\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=\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.\nuint256 onchainDataVersion; // NOLINT: constable-states uninitialized-state.\n\n // Counter of forced action request in block. The key is theblock number.\n mapping(uint256 =\u003e uint256) forcedRequestsInBlock;\n\n // ForcedAction requests: actionHash =\u003e requestTime.\nmapping(bytes32 =\u003e uint256) forcedActionRequests;\n\n // Mapping for timelocked actions.\n // A actionKey =\u003e activation time.\nmapping(bytes32 =\u003e uint256) actionsTimeLock;\n\n // Append only list of requested forced action hashes.\n bytes32[] actionHashList;\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.\n uint256[LAYOUT_LENGTH - 37] private __endGap; // __endGap complements layout toLAYOUT_LENGTH.\n}\n"},"MDeposits.sol":{"content":"/*\n Copyright 2019-2021 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\nabstract contract MDeposits {\n function depositERC20( // NOLINT external-function.\n uint256 starkKey,\n uint256assetType,\n uint256 vaultId,\n uint256 quantizedAmount\n ) public virtual;\n\n function depositEth( // NOLINT external-function.\n uint256 starkKey,\n uint256 assetType,\n uint256 vaultId\n ) public payable virtual;\n}\n"},"MFreezable.sol":{"content":"/*\n Copyright 2019-2021 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\nabstract contractMFreezable {\n /*\n Returns true if the exchange is frozen.\n */\n function isFrozen() public view virtual returns (bool); // NOLINT:external-function.\n\n /*\n Forbids calling the function if the exchange is frozen.\n */\n modifier notFrozen() {\n require(!isFrozen(), \"STATE_IS_FROZEN\");\n _;\n }\n\n function validateFreezeRequest(uint256 requestTime) internal virtual;\n\n /*\nAllows calling the function only if the exchange is frozen.\n */\n modifier onlyFrozen() {\n require(isFrozen(),\"STATE_NOT_FROZEN\");\n _;\n }\n\n /*\n Freezes the exchange.\n */\n function freeze() internal virtual;\n}\n"},"MGovernance.sol":{"content":"/*\n Copyright 2019-2021 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\nabstract contract MGovernance {\n function isGovernor(address testGovernor) internal view virtual returns (bool);\n\n /*\n Allowscalling the function only by a Governor.\n */\n modifier onlyGovernance() {\n require(isGovernor(msg.sender), \"ONLY_GOVERNANCE\");\n_;\n }\n}\n"},"MKeyGetters.sol":{"content":"/*\n Copyright 2019-2021 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\nabstract contract MKeyGetters {\n // NOLINTNEXTLINE: external-function.\n function getEthKey(uint256 ownerKey) public view virtualreturns (address);\n\n function strictGetEthKey(uint256 ownerKey) internal view virtual returns (address);\n\n function isMsgSenderKeyOwner(uint256 ownerKey) internal view virtual returns (bool);\n\n /*\n Allows calling the function only if ownerKey is registered to msg.sender.\n */\n modifier onlyKeyOwner(uint256 ownerKey) {\n // Require the calling user to own the stark key.\n require(msg.sender ==strictGetEthKey(ownerKey), \"MISMATCHING_STARK_ETH_KEYS\");\n _;\n }\n}\n"},"MStarkExForcedActionState.sol":{"content":"/*\n Copyright2019-2021 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 MStarkExForcedActionState {\n functionfullWithdrawActionHash(uint256 starkKey, uint256 vaultId)\n internal\n pure\n virtual\n returns (bytes32);\n\nfunction clearFullWithdrawalRequest(uint256 starkKey, uint256 vaultId) internal virtual;\n\n // NOLINTNEXTLINE: external-function.\n functiongetFullWithdrawalRequest(uint256 starkKey, uint256 vaultId)\n public\n view\n virtual\n returns (uint256 res);\n\nfunction setFullWithdrawalRequest(uint256 starkKey, uint256 vaultId) internal virtual;\n}\n"},"MTokenAssetData.sol":{"content":"/*\n Copyright2019-2021 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 MTokenAssetData {\n // NOLINTNEXTLINE:external-function.\n function getAssetInfo(uint256 assetType) public view virtual returns (bytes memory assetInfo);\n\n functionextractTokenSelector(bytes memory assetInfo)\n internal\n pure\n virtual\n returns (bytes4 selector);\n\n functionisEther(uint256 assetType) internal view virtual returns (bool);\n\n function isERC20(uint256 assetType) internal view virtual returns (bool);\n\n function isERC721(uint256 assetType) internal view virtual returns (bool);\n\n function isFungibleAssetType(uint256 assetType)internal view virtual returns (bool);\n\n function isMintableAssetType(uint256 assetType) internal view virtual returns (bool);\n\n functionextractContractAddress(uint256 assetType) internal view virtual returns (address);\n\n function verifyAssetInfo(bytes memory assetInfo) internalview virtual;\n\n function isNonFungibleAssetInfo(bytes memory assetInfo) internal pure virtual returns (bool);\n\n functioncalculateNftAssetId(uint256 assetType, uint256 tokenId)\n internal\n pure\n virtual\n returns (uint256 assetId);\n\nfunction calculateMintableAssetId(uint256 assetType, bytes memory mintingBlob)\n internal\n pure\n virtual\n returns(uint256 assetId);\n}\n"},"MTokenQuantization.sol":{"content":"/*\n Copyright 2019-2021 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\nabstract contract MTokenQuantization {\n function fromQuantized(uint256 presumedAssetType, uint256 quantizedAmount)\ninternal\n view\n virtual\n returns (uint256 amount);\n\n // NOLINTNEXTLINE: external-function.\n function getQuantum(uint256 presumedAssetType) public view virtual returns (uint256 quantum);\n\n function toQuantized(uint256 presumedAssetType, uint256 amount)\ninternal\n view\n virtual\n returns (uint256 quantizedAmount);\n}\n"},"MTokenTransfers.sol":{"content":"/*\n Copyright2019-2021 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 MTokenTransfers {\n function transferIn(uint256 assetType, uint256 quantizedAmount) internal virtual;\n\n function transferInNft(uint256 assetType, uint256 tokenId) internal virtual;\n\n function transferOut(\n address payable recipient,\n uint256 assetType,\n uint256 quantizedAmount\n ) internalvirtual;\n\n function transferOutNft(\n address recipient,\n uint256 assetType,\n uint256 tokenId\n ) internal virtual;\n\n function transferOutMint(\n uint256 assetType,\n uint256 quantizedAmount,\n address recipient,\n bytes memorymintingBlob\n ) internal virtual;\n}\n"},"ProxyStorage.sol":{"content":"/*\n Copyright 2019-2021 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 \"GovernanceStorage.sol\";\n\n/*\n Holds the Proxy-specific state variables.\n This contract is inheritedby the GovernanceStorage (and indirectly by MainStorage)\n to prevent collision hazard.\n*/\ncontract ProxyStorage is GovernanceStorage {\n //NOLINTNEXTLINE: naming-convention uninitialized-state.\n mapping(address =\u003e bytes32) internal initializationHash_DEPRECATED;\n\n // Thetime after which we can switch to the implementation.\n // Hash(implementation, data, finalize) =\u003e time.\n mapping(bytes32 =\u003euint256) internal enabledTime;\n\n // A central storage of the flags whether implementation has been initialized.\n // Note - it can be usedflexibly enough to accommodate multiple levels of initialization\n // (i.e. using different key salting schemes for different initializationlevels).\n mapping(bytes32 =\u003e bool) internal initialized;\n}\n"},"StarkExForcedActionState.sol":{"content":"/*\n Copyright 2019-2021StarkWare 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 \"StarkExStorage.sol\";\nimport \"MStarkExForcedActionState.sol\";\nimport \"ActionHash.sol\";\n\n/*\n StarkExchange specific action hashses.\n*/\ncontract StarkExForcedActionState is StarkExStorage, ActionHash,MStarkExForcedActionState {\n function fullWithdrawActionHash(uint256 starkKey, uint256 vaultId)\n internal\n pure\noverride\n returns (bytes32)\n {\n return getActionHash(\"FULL_WITHDRAWAL\", abi.encode(starkKey, vaultId));\n }\n\n /*\nImplemented in the FullWithdrawal contracts.\n */\n function clearFullWithdrawalRequest(uint256 starkKey, uint256 vaultId)\ninternal\n virtual\n override\n {\n // Reset escape request.\n delete forcedActionRequests[fullWithdrawActionHash(starkKey, vaultId)];\n }\n\n function getFullWithdrawalRequest(uint256 starkKey, uint256 vaultId)\n public\n view\noverride\n returns (uint256 res)\n {\n // Return request value. Expect zero if the request doesn\u0027t exist or has been serviced, and\n // a non-zero value otherwise.\n res = forcedActionRequests[fullWithdrawActionHash(starkKey, vaultId)];\n }\n\nfunction setFullWithdrawalRequest(uint256 starkKey, uint256 vaultId) internal override {\n // FullWithdrawal is always at premium cost,hence the `true`.\n setActionHash(fullWithdrawActionHash(starkKey, vaultId), true);\n }\n}\n"},"StarkExStorage.sol":{"content":"/*\nCopyright 2019-2021 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 StarkEx App specific state (storage) variables.\n\n ALL State variables that are common to all applications, reside inMainStorage,\n whereas ALL the StarkEx app specific ones reside here.\n*/\ncontract StarkExStorage is MainStorage {\n // Onchain vaultsbalances.\n // A map eth_address =\u003e asset_id =\u003e vault_id =\u003e quantized amount.\n mapping(address =\u003e mapping(uint256=\u003e mapping(uint256 =\u003e uint256))) vaultsBalances;\n\n // Onchain vaults withdrawal lock time.\n // A map eth_address =\u003easset_id =\u003e vault_id =\u003e lock expiration timestamp.\n mapping(address =\u003e mapping(uint256 =\u003e mapping(uint256 =\u003e uint256))) vaultsWithdrawalLocks;\n\n // Enforces the minimal balance requirement (as output by Cairo) on onchain vault updates.\n // When disabled,flash loans are enabled.\n bool strictVaultBalancePolicy; // NOLINT: constable-states, uninitialized-state.\n\n // The default time, inseconds, that an onchain vault is locked for withdrawal after a deposit.\n uint256 public defaultVaultWithdrawalLock; // NOLINT: constable-states.\n\n // Address of the message registry contract that is used to sign and verify L1 orders.\n address public orderRegistryAddress; //NOLINT: constable-states.\n\n // Reserved storage space for Extensibility.\n // Every added MUST be added above the end gap, and the __endGapsize 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"},"SubContractor.sol":{"content":"/*\n Copyright 2019-2021 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 \"Identity.sol\";\n\ninterface SubContractor is Identity {\n function initialize(bytes calldata data) external;\n\n function initializerSize() external view returns (uint256);\n}\n"},"TokenAssetData.sol":{"content":"/*\nCopyright 2019-2021 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\"MTokenAssetData.sol\";\nimport \"Common.sol\";\nimport \"LibConstants.sol\";\n\ncontract TokenAssetData is MainStorage, LibConstants,MTokenAssetData {\n bytes4 internal constant ERC20_SELECTOR = bytes4(keccak256(\"ERC20Token(address)\"));\n bytes4 internal constantETH_SELECTOR = bytes4(keccak256(\"ETH()\"));\n bytes4 internal constant ERC721_SELECTOR = bytes4(keccak256(\"ERC721Token(address,uint256)\"));\nbytes4 internal constant MINTABLE_ERC20_SELECTOR =\n bytes4(keccak256(\"MintableERC20Token(address)\"));\n bytes4 internal constantMINTABLE_ERC721_SELECTOR =\n bytes4(keccak256(\"MintableERC721Token(address,uint256)\"));\n\n // The selector follows the 0x20 bytesassetInfo.length field.\n uint256 internal constant SELECTOR_OFFSET = 0x20;\n uint256 internal constant SELECTOR_SIZE = 4;\n uint256internal constant TOKEN_CONTRACT_ADDRESS_OFFSET = SELECTOR_OFFSET + SELECTOR_SIZE;\n string internal constant NFT_ASSET_ID_PREFIX = \"NFT:\";\nstring internal constant MINTABLE_PREFIX = \"MINTABLE:\";\n\n using Addresses for address;\n\n /*\n Extract the tokenSelector fromassetInfo.\n\n Works like bytes4 tokenSelector = abi.decode(assetInfo, (bytes4))\n but does not revert when assetInfo.length \u003cSELECTOR_OFFSET.\n */\n function extractTokenSelector(bytes memory assetInfo)\n internal\n pure\n override\nreturns (bytes4 selector)\n {\n assembly {\n selector := and(\n0xffffffff00000000000000000000000000000000000000000000000000000000,\n mload(add(assetInfo, SELECTOR_OFFSET))\n )\n}\n }\n\n function getAssetInfo(uint256 assetType) public view override returns (bytes memory assetInfo) {\n // Verify that theregistration is set and valid.\n require(registeredAssetType[assetType], \"ASSET_TYPE_NOT_REGISTERED\");\n\n // Retrieve registration.\n assetInfo = assetTypeToAssetInfo[assetType];\n }\n\n function isEther(uint256 assetType) internal view override returns (bool) {\nreturn extractTokenSelector(getAssetInfo(assetType)) == ETH_SELECTOR;\n }\n\n function isERC20(uint256 assetType) internal viewoverride returns (bool) {\n return extractTokenSelector(getAssetInfo(assetType)) == ERC20_SELECTOR;\n }\n\n function isERC721(uint256assetType) internal view override returns (bool) {\n return extractTokenSelector(getAssetInfo(assetType)) == ERC721_SELECTOR;\n }\n\nfunction isFungibleAssetType(uint256 assetType) internal view override returns (bool) {\n bytes4 tokenSelector = extractTokenSelector(getAssetInfo(assetType));\n return\n tokenSelector == ETH_SELECTOR ||\n tokenSelector == ERC20_SELECTOR ||\ntokenSelector == MINTABLE_ERC20_SELECTOR;\n }\n\n function isMintableAssetType(uint256 assetType) internal view override returns (bool){\n bytes4 tokenSelector = extractTokenSelector(getAssetInfo(assetType));\n return\n tokenSelector ==MINTABLE_ERC20_SELECTOR || tokenSelector == MINTABLE_ERC721_SELECTOR;\n }\n\n function isTokenSupported(bytes4 tokenSelector) private purereturns (bool) {\n return\n tokenSelector == ETH_SELECTOR ||\n tokenSelector == ERC20_SELECTOR ||\ntokenSelector == ERC721_SELECTOR ||\n tokenSelector == MINTABLE_ERC20_SELECTOR ||\n tokenSelector == MINTABLE_ERC721_SELECTOR;\n }\n\n function extractContractAddressFromAssetInfo(bytes memory assetInfo)\n private\n pure\n returns (address)\n{\n uint256 offset = TOKEN_CONTRACT_ADDRESS_OFFSET;\n uint256 res;\n assembly {\n res := mload(add(assetInfo,offset))\n }\n return address(res);\n }\n\n function extractContractAddress(uint256 assetType) internal view override returns(address) {\n return extractContractAddressFromAssetInfo(getAssetInfo(assetType));\n }\n\n function verifyAssetInfo(bytes memoryassetInfo) internal view override {\n bytes4 tokenSelector = extractTokenSelector(assetInfo);\n\n // Ensure the selector is of anasset type we know.\n require(isTokenSupported(tokenSelector), \"UNSUPPORTED_TOKEN_TYPE\");\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 a uint256 (zero padded),\n // thus its length is 0x04 + 0x20 = 0x24.\n require(assetInfo.length ==0x24, \"INVALID_ASSET_STRING\");\n address tokenAddress = extractContractAddressFromAssetInfo(assetInfo);\n require(tokenAddress.isContract(), \"BAD_TOKEN_ADDRESS\");\n }\n }\n\n function isNonFungibleAssetInfo(bytes memory assetInfo) internal pureoverride returns (bool) {\n bytes4 tokenSelector = extractTokenSelector(assetInfo);\n return tokenSelector == ERC721_SELECTOR ||tokenSelector == MINTABLE_ERC721_SELECTOR;\n }\n\n function calculateNftAssetId(uint256 assetType, uint256 tokenId)\n internal\npure\n override\n returns (uint256 assetId)\n {\n assetId =\n uint256(keccak256(abi.encodePacked(NFT_ASSET_ID_PREFIX, assetType, tokenId))) \u0026\n MASK_250;\n }\n\n function calculateMintableAssetId(uint256 assetType, bytesmemory mintingBlob)\n internal\n pure\n override\n returns (uint256 assetId)\n {\n uint256 blobHash = uint256(keccak256(mintingBlob));\n assetId =\n (uint256(keccak256(abi.encodePacked(MINTABLE_PREFIX, assetType, blobHash))) \u0026\nMASK_240) |\n MINTABLE_ASSET_ID_FLAG;\n }\n}\n"},"TokenQuantization.sol":{"content":"/*\n Copyright 2019-2021 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 \"MainStorage.sol\";\nimport \"MTokenQuantization.sol\";\n\ncontractTokenQuantization is MainStorage, MTokenQuantization {\n function fromQuantized(uint256 presumedAssetType, uint256 quantizedAmount)\ninternal\n view\n override\n returns (uint256 amount)\n {\n uint256 quantum = getQuantum(presumedAssetType);\namount = quantizedAmount * quantum;\n require(amount / quantum == quantizedAmount, \"DEQUANTIZATION_OVERFLOW\");\n }\n\n functiongetQuantum(uint256 presumedAssetType) public view override returns (uint256 quantum) {\n if (!registeredAssetType[presumedAssetType]) {\n// Default quantization, for NFTs etc.\n quantum = 1;\n } else {\n // Retrieve registration.\nquantum = assetTypeToQuantum[presumedAssetType];\n }\n }\n\n function toQuantized(uint256 presumedAssetType, uint256 amount)\ninternal\n view\n override\n returns (uint256 quantizedAmount)\n {\n uint256 quantum = getQuantum(presumedAssetType);\n require(amount % quantum == 0, \"INVALID_AMOUNT\");\n quantizedAmount = amount / quantum;\n }\n}\n"},"TokenRegister.sol":{"content":"/*\n Copyright 2019-2021 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 \"LibConstants.sol\";\nimport \"MGovernance.sol\";\nimport \"MTokenAssetData.sol\";\nimport \"IERC20.sol\";\nimport \"MainStorage.sol\";\n\n/**\n Registrationof a new token (:sol:func:`registerToken`) entails defining a new asset type within\n the system, and associating it with an `assetInfo` arrayof\n bytes and a quantization factor (`quantum`).\n\n The `assetInfo` is a byte array, with a size depending on the token.\n For ETH, assetInfois 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 as follows:\n\n\n The `quantum` quantization factor defines the multiplicative transformation from the native token\ndenomination as a 256b unsigned integer to a 63b unsigned integer representation as used by the\n Stark exchange. Only amounts in the nativerepresentation that represent an integer number of\n quanta are allowed in the system.\n\n The asset type is restricted to be the result of ahash 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 Once registered, tokens cannot be removed from the system, as theirIDs may be used by off-chain\n accounts.\n\n New tokens may only be registered by a Token Administrator. A Token Administrator may be instantly\nappointed or removed by the contract Governor (see :sol:mod:`MainGovernance`). Typically, the\n Token Administrator\u0027s private key should bekept in a cold wallet.\n*/\nabstract contract TokenRegister is MainStorage, LibConstants, MGovernance, MTokenAssetData {\n eventLogTokenRegistered(uint256 assetType, bytes assetInfo, uint256 quantum);\n event LogTokenAdminAdded(address tokenAdmin);\n eventLogTokenAdminRemoved(address tokenAdmin);\n\n modifier onlyTokensAdmin() {\n require(isTokenAdmin(msg.sender), \"ONLY_TOKENS_ADMIN\");\n_;\n }\n\n function isTokenAdmin(address testedAdmin) public view returns (bool) {\n return tokenAdmins[testedAdmin];\n}\n\n function registerTokenAdmin(address newAdmin) external onlyGovernance {\n tokenAdmins[newAdmin] = true;\n emitLogTokenAdminAdded(newAdmin);\n }\n\n function unregisterTokenAdmin(address oldAdmin) external onlyGovernance {\ntokenAdmins[oldAdmin] = false;\n emit LogTokenAdminRemoved(oldAdmin);\n }\n\n function isAssetRegistered(uint256 assetType) publicview returns (bool) {\n return registeredAssetType[assetType];\n }\n\n /*\n Registers a new asset to the system.\n Onceadded, it can not be removed and there is a limited number\n of slots available.\n */\n function registerToken(\n uint256assetType,\n bytes memory assetInfo,\n uint256 quantum\n ) public virtual onlyTokensAdmin {\n // Make sure it is notinvalid or already registered.\n require(!isAssetRegistered(assetType), \"ASSET_ALREADY_REGISTERED\");\n require(assetType \u003cK_MODULUS, \"INVALID_ASSET_TYPE\");\n require(quantum \u003e 0, \"INVALID_QUANTUM\");\n require(quantum \u003c QUANTUM_UPPER_BOUND,\"INVALID_QUANTUM\");\n\n // Require that the assetType is the hash of the assetInfo and quantum truncated to 250 bits.\n uint256enforcedId = uint256(keccak256(abi.encodePacked(assetInfo, quantum))) \u0026 MASK_250;\n require(assetType == enforcedId,\"INVALID_ASSET_TYPE\");\n\n verifyAssetInfo(assetInfo);\n // NFTs quantum must equal one.\n if (isNonFungibleAssetInfo(assetInfo)) {\n require(quantum == 1, \"INVALID_NFT_QUANTUM\");\n }\n\n // Add token to the in-storage structures.\nregisteredAssetType[assetType] = true;\n assetTypeToAssetInfo[assetType] = assetInfo;\n assetTypeToQuantum[assetType] = quantum;\n\n // Log the registration of a new token.\n emit LogTokenRegistered(assetType, assetInfo, quantum);\n }\n\n functionregisterToken(uint256 assetType, bytes calldata assetInfo) external virtual {\n registerToken(assetType, assetInfo, 1);\n }\n}\n"},"TokensAndRamping.sol":{"content":"/*\n Copyright 2019-2021 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 \"StarkExForcedActionState.sol\";\nimport \"ERC721Receiver.sol\";\nimport \"Freezable.sol\";\nimport \"KeyGetters.sol\";\nimport\"TokenRegister.sol\";\nimport \"TokenTransfers.sol\";\nimport \"Users.sol\";\nimport \"MainGovernance.sol\";\nimport \"AcceptModifications.sol\";\nimport \"CompositeActions.sol\";\nimport \"Deposits.sol\";\nimport \"TokenAssetData.sol\";\nimport \"TokenQuantization.sol\";\nimport\"Withdrawals.sol\";\nimport \"SubContractor.sol\";\n\ncontract TokensAndRamping is\n ERC721Receiver,\n SubContractor,\n Freezable,\nMainGovernance,\n AcceptModifications,\n StarkExForcedActionState,\n TokenAssetData,\n TokenQuantization,\n TokenRegister,\nTokenTransfers,\n KeyGetters,\n Users,\n Deposits,\n CompositeActions,\n Withdrawals\n{\n function initialize(\n bytescalldata /* data */\n ) external override {\n revert(\"NOT_IMPLEMENTED\");\n }\n\n function initializerSize() external viewoverride returns (uint256) {\n return 0;\n }\n\n function identify() external pure override returns (string memory) {\n return\"StarkWare_TokensAndRamping_2020_1\";\n }\n}\n"},"TokenTransfers.sol":{"content":"/*\n Copyright 2019-2021 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 \"Common.sol\";\nimport \"MTokenTransfers.sol\";\nimport \"MTokenAssetData.sol\";\nimport \"MTokenQuantization.sol\";\nimport \"IERC20.sol\";\n\n/*\n Implements various transferIn and transferOut functionalities.\n*/\nabstractcontract TokenTransfers is MTokenQuantization, MTokenAssetData, MTokenTransfers {\n using Addresses for address;\n using Addresses foraddress payable;\n\n /*\n Transfers funds from msg.sender to the exchange.\n */\n function transferIn(uint256 assetType, uint256quantizedAmount) internal override {\n uint256 amount = fromQuantized(assetType, quantizedAmount);\n if (isERC20(assetType)) {\naddress tokenAddress = extractContractAddress(assetType);\n IERC20 token = IERC20(tokenAddress);\n uint256exchangeBalanceBefore = token.balanceOf(address(this));\n bytes memory callData = abi.encodeWithSelector(\n token.transferFrom.selector,\n msg.sender,\n address(this),\n amount\n );\ntokenAddress.safeTokenContractCall(callData);\n uint256 exchangeBalanceAfter = token.balanceOf(address(this));\n require(exchangeBalanceAfter \u003e= exchangeBalanceBefore, \"OVERFLOW\");\n // NOLINTNEXTLINE(incorrect-equality): strict equality needed.\nrequire(\n exchangeBalanceAfter == exchangeBalanceBefore + amount,\n \"INCORRECT_AMOUNT_TRANSFERRED\"\n);\n } else if (isEther(assetType)) {\n require(msg.value == amount, \"INCORRECT_DEPOSIT_AMOUNT\");\n } else {\nrevert(\"UNSUPPORTED_TOKEN_TYPE\");\n }\n }\n\n function transferInNft(uint256 assetType, uint256 tokenId) internal override{\n require(isERC721(assetType), \"NOT_ERC721_TOKEN\");\n address tokenAddress = extractContractAddress(assetType);\ntokenAddress.safeTokenContractCall(\n abi.encodeWithSignature(\n \"safeTransferFrom(address,address,uint256)\",\nmsg.sender,\n address(this),\n tokenId\n )\n );\n }\n\n /*\n Transfers fundsfrom the exchange to recipient.\n */\n function transferOut(\n address payable recipient,\n uint256 assetType,\n uint256quantizedAmount\n ) internal override {\n // Make sure we don\u0027t accidentally burn funds.\n require(recipient != address(0x0),\"INVALID_RECIPIENT\");\n uint256 amount = fromQuantized(assetType, quantizedAmount);\n if (isERC20(assetType)) {\naddress tokenAddress = extractContractAddress(assetType);\n IERC20 token = IERC20(tokenAddress);\n uint256exchangeBalanceBefore = token.balanceOf(address(this));\n bytes memory callData = abi.encodeWithSelector(\n token.transfer.selector,\n recipient,\n amount\n );\n tokenAddress.safeTokenContractCall(callData);\n uint256 exchangeBalanceAfter = token.balanceOf(address(this));\n require(exchangeBalanceAfter \u003c=exchangeBalanceBefore, \"UNDERFLOW\");\n // NOLINTNEXTLINE(incorrect-equality): strict equality needed.\n require(\nexchangeBalanceAfter == exchangeBalanceBefore - amount,\n \"INCORRECT_AMOUNT_TRANSFERRED\"\n );\n } else if(isEther(assetType)) {\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(\n address recipient,\nuint256 assetType,\n uint256 tokenId\n ) internal override {\n // Make sure we don\u0027t accidentally burn funds.\nrequire(recipient != address(0x0), \"INVALID_RECIPIENT\");\n require(isERC721(assetType), \"NOT_ERC721_TOKEN\");\n addresstokenAddress = extractContractAddress(assetType);\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 address recipient,\nbytes memory mintingBlob\n ) internal override {\n // Make sure we don\u0027t accidentally burn funds.\n require(recipient!= address(0x0), \"INVALID_RECIPIENT\");\n require(isMintableAssetType(assetType), \"NON_MINTABLE_ASSET_TYPE\");\n uint256 amount =fromQuantized(assetType, quantizedAmount);\n address tokenAddress = extractContractAddress(assetType);\n tokenAddress.safeTokenContractCall(\n abi.encodeWithSignature(\n \"mintFor(address,uint256,bytes)\",\n recipient,\namount,\n mintingBlob\n )\n );\n }\n}\n"},"Users.sol":{"content":"/*\n Copyright 2019-2021StarkWare 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 \"ECDSA.sol\";\nimport \"MainStorage.sol\";\nimport \"LibConstants.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.\n\n The Stark-friendly elliptic curve used is defined asfollows:\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 User registration is the mechanism that associates an Ethereumaddress with a StarkKey\n within the main contract context.\n\n User registrations that were done on previous versions (up to v3.0) are stillsupported.\n However, in most cases, there is no need to register a user.\n The only flows that require user registration are the anti-concorshipflows:\n forced actions and deposit cancellation.\n\n User registration is performed by calling :sol:func:`registerEthAddress` with theselected\n Stark Key, representing an `x` coordinate on the Stark-friendly elliptic curve,\n and the `y` coordinate of the key on the curve (dueto the nature of the curve,\n only two such possible `y` coordinates exist).\n\n The registration is accepted if the following holds:\n\n 1. Thekey registered is not zero and has not been registered in the past by the user or anyone else.\n 2. The key provided represents a valid point onthe Stark-friendly elliptic curve.\n 3. The linkage between the provided Ethereum address and the selected Stark Key is signed using\n theprivte key of the selected Stark Key.\n\n If the above holds, the Ethereum address is registered by the contract, mapping it to the Stark Key.\n*/\nabstract contract Users is MainStorage, LibConstants {\n event LogUserRegistered(address ethKey, uint256 starkKey, address sender);\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 functionregisterSender(uint256 starkKey, bytes calldata starkSignature) external {\n registerEthAddress(msg.sender, starkKey, starkSignature);\n}\n\n function registerEthAddress(\n address ethKey,\n uint256 starkKey,\n bytes calldata starkSignature\n ) public {\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(starkSignature.length == 32 * 3,\"INVALID_STARK_SIGNATURE_LENGTH\");\n\n bytes memory sig = starkSignature;\n (uint256 r, uint256 s, uint256 StarkKeyY) = abi.decode(sig, (uint256, uint256, uint256));\n\n uint256 msgHash = uint256(\n keccak256(abi.encodePacked(\"UserRegistration:\", ethKey,starkKey))\n ) % ECDSA.EC_ORDER;\n\n ECDSA.verify(msgHash, r, s, starkKey, StarkKeyY);\n\n // Update state.\nethKeys[starkKey] = ethKey;\n\n // Log new user.\n emit LogUserRegistered(ethKey, starkKey, msg.sender);\n }\n\n functionfieldPow(uint256 base, uint256 exponent) internal view returns (uint256) {\n // NOLINTNEXTLINE: low-level-calls reentrancy-events reentrancy-no-eth.\n (bool success, bytes memory 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 functionisQuadraticResidue(uint256 fieldElement) private view returns (bool) {\n return 1 == fieldPow(fieldElement, ((K_MODULUS - 1) / 2));\n}\n}\n"},"Withdrawals.sol":{"content":"/*\n Copyright 2019-2021 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 \"MAcceptModifications.sol\";\nimport \"MTokenQuantization.sol\";\nimport \"MTokenAssetData.sol\";\nimport \"MFreezable.sol\";\nimport\"MKeyGetters.sol\";\nimport \"MTokenTransfers.sol\";\nimport \"MainStorage.sol\";\n\n/**\n For a user to perform a withdrawal operation from theStark Exchange during normal operation\n two calls are required:\n\n 1. A call to an offchain exchange API, requesting a withdrawal from a useraccount (vault).\n 2. A call to the on-chain :sol:func:`withdraw` function to perform the actual withdrawal of funds transferring them to theusers Eth or ERC20 account (depending on the token type).\n\n For simplicity, hereafter it is assumed that all tokens are ERC20 tokens but thetext below\n applies to Eth in the same manner.\n\n In the first call mentioned above, anyone can call the API to request the withdrawal of an\namount from a given vault. Following the request, the exchange may include the withdrawal in a\n STARK proof. The submission of a proof thenresults in the addition of the amount(s) withdrawn to\n an on-chain pending withdrawals account under the stark key of the vault owner and theappropriate\n asset ID. At the same time, this also implies that this amount is deducted from the off-chain\n vault.\n\n Once the amount to bewithdrawn has been transfered to the on-chain pending withdrawals account,\n the user may perform the second call mentioned above to complete thetransfer of funds from the\n Stark Exchange contract to the appropriate ERC20 account. Only a user holding the Eth key\n corresponding to theStark Key of a pending withdrawals account may perform this operation.\n\n It is possible that for multiple withdrawal calls to the API, a singlewithdrawal call to the\n contract may retrieve all funds, 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 of ERC20 tokens\n in the pending withdrawal account times the quantization factor istransferred to the ERC20\n account of the user.\n\n A withdrawal request cannot be cancelled. Once funds reach the pending withdrawals account\non-chain, they cannot be moved back into an off-chain vault before completion of the withdrawal\n to the ERC20 account of the user.\n\n In theevent that the exchange reaches a frozen state the user may perform a withdrawal operation\n via an alternative flow, known as the \"Escape\" flow. In this flow, the API call above is replaced\n with an :sol:func:`escape` call to the on-chain contract (see :sol:mod:`Escapes`) proving the\nownership 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 tocomplete the operation.\n*/\nabstract contract Withdrawals is\n MainStorage,\n MAcceptModifications,\n MTokenQuantization,\nMTokenAssetData,\n MFreezable,\n MKeyGetters,\n MTokenTransfers\n{\n event LogWithdrawalPerformed(\n uint256 ownerKey,\nuint256 assetType,\n uint256 nonQuantizedAmount,\n uint256 quantizedAmount,\n address recipient\n );\n\n eventLogNftWithdrawalPerformed(\n uint256 ownerKey,\n uint256 assetType,\n uint256 tokenId,\n uint256 assetId,\naddress recipient\n );\n\n event LogMintWithdrawalPerformed(\n uint256 ownerKey,\n uint256 assetType,\n uint256nonQuantizedAmount,\n uint256 quantizedAmount,\n uint256 assetId\n );\n\n function getWithdrawalBalance(uint256 ownerKey,uint256 assetId)\n external\n view\n returns (uint256 balance)\n {\n uint256 presumedAssetType = assetId;\nbalance = fromQuantized(presumedAssetType, pendingWithdrawals[ownerKey][assetId]);\n }\n\n /*\n Moves funds from the pending withdrawalaccount to the owner address.\n Note: this function can be called by anyone.\n Can be called normally while frozen.\n */\n functionwithdraw(uint256 ownerKey, uint256 assetType) external {\n address payable recipient = payable(strictGetEthKey(ownerKey));\n require(!isMintableAssetType(assetType), \"MINTABLE_ASSET_TYPE\");\n require(isFungibleAssetType(assetType), \"NON_FUNGIBLE_ASSET_TYPE\");\nuint256 assetId = assetType;\n // Fetch and clear quantized amount.\n uint256 quantizedAmount =pendingWithdrawals[ownerKey][assetId];\n pendingWithdrawals[ownerKey][assetId] = 0;\n\n // Transfer funds.\n transferOut(recipient, assetType, quantizedAmount);\n emit LogWithdrawalPerformed(\n ownerKey,\n assetType,\nfromQuantized(assetType, quantizedAmount),\n quantizedAmount,\n recipient\n );\n }\n\n /*\n Allowswithdrawal of an NFT to its owner account.\n Note: this function can be called by anyone.\n This function can be called normally whilefrozen.\n */\n function withdrawNft(\n uint256 ownerKey,\n uint256 assetType,\n uint256 tokenId // No notFrozen modifier: This function can always be used, even when frozen.\n ) external {\n address recipient = strictGetEthKey(ownerKey);\n //Calculate assetId.\n uint256 assetId = calculateNftAssetId(assetType, tokenId);\n require(!isMintableAssetType(assetType),\"MINTABLE_ASSET_TYPE\");\n require(!isFungibleAssetType(assetType), \"FUNGIBLE_ASSET_TYPE\");\n require(pendingWithdrawals[ownerKey][assetId] == 1, \"ILLEGAL_NFT_BALANCE\");\n pendingWithdrawals[ownerKey][assetId] = 0;\n\n // Transferfunds.\n transferOutNft(recipient, assetType, tokenId);\n emit LogNftWithdrawalPerformed(ownerKey, assetType, tokenId, assetId,recipient);\n }\n\n function withdrawAndMint(\n uint256 ownerKey,\n uint256 assetType,\n bytes calldata mintingBlob\n) external {\n address recipient = strictGetEthKey(ownerKey);\n require(registeredAssetType[assetType], \"INVALID_ASSET_TYPE\");\nrequire(isMintableAssetType(assetType), \"NON_MINTABLE_ASSET_TYPE\");\n uint256 assetId = calculateMintableAssetId(assetType,mintingBlob);\n require(pendingWithdrawals[ownerKey][assetId] \u003e 0, \"NO_PENDING_WITHDRAWAL_BALANCE\");\n uint256 quantizedAmount= pendingWithdrawals[ownerKey][assetId];\n pendingWithdrawals[ownerKey][assetId] = 0;\n // Transfer funds.\n transferOutMint(assetType, quantizedAmount, recipient, mintingBlob);\n emit LogMintWithdrawalPerformed(\n ownerKey,\n assetType,\nfromQuantized(assetType, quantizedAmount),\n quantizedAmount,\n assetId\n );\n }\n}\n"}}