ETH Price: $3,004.81 (+4.23%)
Gas: 2 Gwei

Contract

0x613ee54C54D5548627064B4D648942bF3648f376
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Value
Full Withdrawal ...193989322024-03-09 17:07:59118 days ago1710004079IN
0x613ee54C...F3648f376
0 ETH0.0018170368.14064963
Full Withdrawal ...193812942024-03-07 5:46:23121 days ago1709790383IN
0x613ee54C...F3648f376
0 ETH0.0015572558.39863375
Full Withdrawal ...193812812024-03-07 5:43:47121 days ago1709790227IN
0x613ee54C...F3648f376
0 ETH0.0015074656.53138127
0x60806040154525562022-09-01 11:16:14673 days ago1662030974IN
 Create: ForcedActions
0 ETH0.0346053416.22645889

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ForcedActions

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 100 runs

Other Settings:
istanbul EvmVersion, Apache-2.0 license
File 1 of 25 : ForcedActions.sol
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

import "FullWithdrawals.sol";
import "StarkExForcedActionState.sol";
import "Freezable.sol";
import "KeyGetters.sol";
import "MainGovernance.sol";
import "Users.sol";
import "SubContractor.sol";

contract ForcedActions is
    SubContractor,
    MainGovernance,
    Freezable,
    KeyGetters,
    Users,
    FullWithdrawals,
    StarkExForcedActionState
{
    function initialize(
        bytes calldata /* data */
    ) external override {
        revert("NOT_IMPLEMENTED");
    }

    function initializerSize() external view override returns (uint256) {
        return 0;
    }

    function validatedSelectors()
        external
        pure
        virtual
        override
        returns (bytes4[] memory selectors)
    {
        uint256 len_ = 3;
        uint256 index_ = 0;

        selectors = new bytes4[](len_);
        selectors[index_++] = FullWithdrawals.freezeRequest.selector;
        selectors[index_++] = FullWithdrawals.fullWithdrawalRequest.selector;
        selectors[index_++] = Users.registerEthAddress.selector;
        require(index_ == len_, "INCORRECT_SELECTORS_ARRAY_LENGTH");
    }

    function identify() external pure override returns (string memory) {
        return "StarkWare_ForcedActions_2022_3";
    }
}

File 2 of 25 : MainStorage.sol
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

import "ProxyStorage.sol";
import "Common.sol";

/*
  Holds ALL the main contract state (storage) variables.
*/
contract MainStorage is ProxyStorage {
    uint256 internal constant LAYOUT_LENGTH = 2**64;

    address escapeVerifierAddress; // NOLINT: constable-states.

    // Global dex-frozen flag.
    bool stateFrozen; // NOLINT: constable-states.

    // Time when unFreeze can be successfully called (UNFREEZE_DELAY after freeze).
    uint256 unFreezeTime; // NOLINT: constable-states.

    // Pending deposits.
    // A map STARK key => asset id => vault id => quantized amount.
    mapping(uint256 => mapping(uint256 => mapping(uint256 => uint256))) pendingDeposits;

    // Cancellation requests.
    // A map STARK key => asset id => vault id => request timestamp.
    mapping(uint256 => mapping(uint256 => mapping(uint256 => uint256))) cancellationRequests;

    // Pending withdrawals.
    // A map STARK key => asset id => quantized amount.
    mapping(uint256 => mapping(uint256 => uint256)) pendingWithdrawals;

    // vault_id => escape used boolean.
    mapping(uint256 => bool) escapesUsed;

    // Number of escapes that were performed when frozen.
    uint256 escapesUsedCount; // NOLINT: constable-states.

    // NOTE: fullWithdrawalRequests is deprecated, and replaced by forcedActionRequests.
    // NOLINTNEXTLINE naming-convention.
    mapping(uint256 => mapping(uint256 => uint256)) fullWithdrawalRequests_DEPRECATED;

    // State sequence number.
    uint256 sequenceNumber; // NOLINT: constable-states uninitialized-state.

    // Validium Vaults Tree Root & Height.
    uint256 validiumVaultRoot; // NOLINT: constable-states uninitialized-state.
    uint256 validiumTreeHeight; // NOLINT: constable-states uninitialized-state.

    // Order Tree Root & Height.
    uint256 orderRoot; // NOLINT: constable-states uninitialized-state.
    uint256 orderTreeHeight; // NOLINT: constable-states uninitialized-state.

    // True if and only if the address is allowed to add tokens.
    mapping(address => bool) tokenAdmins;

    // This mapping is no longer in use, remains for backwards compatibility.
    mapping(address => bool) userAdmins_DEPRECATED; // NOLINT: naming-convention.

    // True if and only if the address is an operator (allowed to update state).
    mapping(address => bool) operators; // NOLINT: uninitialized-state.

    // Mapping of contract ID to asset data.
    mapping(uint256 => bytes) assetTypeToAssetInfo; // NOLINT: uninitialized-state.

    // Mapping of registered contract IDs.
    mapping(uint256 => bool) registeredAssetType; // NOLINT: uninitialized-state.

    // Mapping from contract ID to quantum.
    mapping(uint256 => uint256) assetTypeToQuantum; // NOLINT: uninitialized-state.

    // This mapping is no longer in use, remains for backwards compatibility.
    mapping(address => uint256) starkKeys_DEPRECATED; // NOLINT: naming-convention.

    // Mapping from STARK public key to the Ethereum public key of its owner.
    mapping(uint256 => address) ethKeys; // NOLINT: uninitialized-state.

    // Timelocked state transition and availability verification chain.
    StarkExTypes.ApprovalChainData verifiersChain;
    StarkExTypes.ApprovalChainData availabilityVerifiersChain;

    // Batch id of last accepted proof.
    uint256 lastBatchId; // NOLINT: constable-states uninitialized-state.

    // Mapping between sub-contract index to sub-contract address.
    mapping(uint256 => address) subContracts; // NOLINT: uninitialized-state.

    mapping(uint256 => bool) permissiveAssetType_DEPRECATED; // NOLINT: naming-convention.
    // ---- END OF MAIN STORAGE AS DEPLOYED IN STARKEX2.0 ----

    // Onchain-data version configured for the system.
    uint256 onchainDataVersion_DEPRECATED; // NOLINT: naming-convention constable-states.

    // Counter of forced action request in block. The key is the block number.
    mapping(uint256 => uint256) forcedRequestsInBlock;

    // ForcedAction requests: actionHash => requestTime.
    mapping(bytes32 => uint256) forcedActionRequests;

    // Mapping for timelocked actions.
    // A actionKey => activation time.
    mapping(bytes32 => uint256) actionsTimeLock;

    // Append only list of requested forced action hashes.
    bytes32[] actionHashList;
    // ---- END OF MAIN STORAGE AS DEPLOYED IN STARKEX3.0 ----
    // ---- END OF MAIN STORAGE AS DEPLOYED IN STARKEX4.0 ----

    // Rollup Vaults Tree Root & Height.
    uint256 rollupVaultRoot; // NOLINT: constable-states uninitialized-state.
    uint256 rollupTreeHeight; // NOLINT: constable-states uninitialized-state.

    uint256 globalConfigCode; // NOLINT: constable-states uninitialized-state.

    // Reserved storage space for Extensibility.
    // Every added MUST be added above the end gap, and the __endGap size must be reduced
    // accordingly.
    // NOLINTNEXTLINE: naming-convention.
    uint256[LAYOUT_LENGTH - 40] private __endGap; // __endGap complements layout to LAYOUT_LENGTH.
}

File 3 of 25 : Users.sol
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

import "ECDSA.sol";
import "MainStorage.sol";
import "LibConstants.sol";

/**
  Users of the Stark Exchange are identified within the exchange by their Stark Key which is a
  public key defined over a Stark-friendly elliptic curve that is different from the standard
  Ethereum elliptic curve.

  The Stark-friendly elliptic curve used is defined as follows:

  .. math:: y^2 = (x^3 + \alpha \cdot x + \beta) \% p

  where:

  .. math:: \alpha = 1
  .. math:: \beta = 3141592653589793238462643383279502884197169399375105820974944592307816406665
  .. math:: p = 3618502788666131213697322783095070105623107215331596699973092056135872020481

  User registration is the mechanism that associates an Ethereum address with a StarkKey
  within the main contract context.

  User registrations that were done on previous versions (up to v3.0) are still supported.
  However, in most cases, there is no need to register a user.
  The only flows that require user registration are the anti-concorship flows:
  forced actions and deposit cancellation.

  User registration is performed by calling :sol:func:`registerEthAddress` with the selected
  Stark Key, representing an `x` coordinate on the Stark-friendly elliptic curve,
  and the `y` coordinate of the key on the curve (due to the nature of the curve,
  only two such possible `y` coordinates exist).

  The registration is accepted if the following holds:

  1. The key registered is not zero and has not been registered in the past by the user or anyone else.
  2. The key provided represents a valid point on the Stark-friendly elliptic curve.
  3. The linkage between the provided Ethereum address and the selected Stark Key is signed using
     the privte key of the selected Stark Key.

  If the above holds, the Ethereum address is registered by the contract, mapping it to the Stark Key.
*/
abstract contract Users is MainStorage, LibConstants {
    event LogUserRegistered(address ethKey, uint256 starkKey, address sender);

    function isOnCurve(uint256 starkKey) private view returns (bool) {
        uint256 xCubed = mulmod(mulmod(starkKey, starkKey, K_MODULUS), starkKey, K_MODULUS);
        return isQuadraticResidue(addmod(addmod(xCubed, starkKey, K_MODULUS), K_BETA, K_MODULUS));
    }

    function registerSender(uint256 starkKey, bytes calldata starkSignature) external {
        registerEthAddress(msg.sender, starkKey, starkSignature);
    }

    function registerEthAddress(
        address ethKey,
        uint256 starkKey,
        bytes calldata starkSignature
    ) public {
        // Validate keys and availability.
        require(starkKey != 0, "INVALID_STARK_KEY");
        require(starkKey < K_MODULUS, "INVALID_STARK_KEY");
        require(ethKey != ZERO_ADDRESS, "INVALID_ETH_ADDRESS");
        require(ethKeys[starkKey] == ZERO_ADDRESS, "STARK_KEY_UNAVAILABLE");
        require(isOnCurve(starkKey), "INVALID_STARK_KEY");
        require(starkSignature.length == 32 * 3, "INVALID_STARK_SIGNATURE_LENGTH");

        bytes memory sig = starkSignature;
        (uint256 r, uint256 s, uint256 StarkKeyY) = abi.decode(sig, (uint256, uint256, uint256));

        uint256 msgHash = uint256(
            keccak256(abi.encodePacked("UserRegistration:", ethKey, starkKey))
        ) % ECDSA.EC_ORDER;

        ECDSA.verify(msgHash, r, s, starkKey, StarkKeyY);

        // Update state.
        ethKeys[starkKey] = ethKey;

        // Log new user.
        emit LogUserRegistered(ethKey, starkKey, msg.sender);
    }

    function fieldPow(uint256 base, uint256 exponent) internal view returns (uint256) {
        // NOLINTNEXTLINE: low-level-calls reentrancy-events reentrancy-no-eth.
        (bool success, bytes memory returndata) = address(5).staticcall(
            abi.encode(0x20, 0x20, 0x20, base, exponent, K_MODULUS)
        );
        require(success, string(returndata));
        return abi.decode(returndata, (uint256));
    }

    function isQuadraticResidue(uint256 fieldElement) private view returns (bool) {
        return 1 == fieldPow(fieldElement, ((K_MODULUS - 1) / 2));
    }
}

File 4 of 25 : GovernanceStorage.sol
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;
import "MGovernance.sol";

/*
  Holds the governance slots for ALL entities, including proxy and the main contract.
*/
contract GovernanceStorage {
    // A map from a Governor tag to its own GovernanceInfoStruct.
    mapping(string => GovernanceInfoStruct) internal governanceInfo; //NOLINT uninitialized-state.
}

File 5 of 25 : KeyGetters.sol
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

import "MainStorage.sol";
import "MKeyGetters.sol";

/*
  Implements MKeyGetters.
*/
contract KeyGetters is MainStorage, MKeyGetters {
    uint256 internal constant MASK_ADDRESS = (1 << 160) - 1;

    /*
      Returns the Ethereum public key (address) that owns the given ownerKey.
      If the ownerKey size is within the range of an Ethereum address (i.e. < 2**160)
      it returns the owner key itself.

      If the ownerKey is larger than a potential eth address, the eth address for which the starkKey
      was registered is returned, and 0 if the starkKey is not registered.

      Note - prior to version 4.0 this function reverted on an unregistered starkKey.
      For a variant of this function that reverts on an unregistered starkKey, use strictGetEthKey.
    */
    function getEthKey(uint256 ownerKey) public view override returns (address) {
        address registeredEth = ethKeys[ownerKey];

        if (registeredEth != address(0x0)) {
            return registeredEth;
        }

        return ownerKey == (ownerKey & MASK_ADDRESS) ? address(ownerKey) : address(0x0);
    }

    /*
      Same as getEthKey, but fails when a stark key is not registered.
    */
    function strictGetEthKey(uint256 ownerKey) internal view override returns (address ethKey) {
        ethKey = getEthKey(ownerKey);
        require(ethKey != address(0x0), "USER_UNREGISTERED");
    }

    function isMsgSenderKeyOwner(uint256 ownerKey) internal view override returns (bool) {
        return msg.sender == getEthKey(ownerKey);
    }
}

File 6 of 25 : Common.sol
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

/*
  Common Utility librarries.
  I. Addresses (extending address).
*/
library Addresses {
    function isContract(address account) internal view returns (bool) {
        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    function performEthTransfer(address recipient, uint256 amount) internal {
        (bool success, ) = recipient.call{value: amount}(""); // NOLINT: low-level-calls.
        require(success, "ETH_TRANSFER_FAILED");
    }

    /*
      Safe wrapper around ERC20/ERC721 calls.
      This is required because many deployed ERC20 contracts don't return a value.
      See https://github.com/ethereum/solidity/issues/4116.
    */
    function safeTokenContractCall(address tokenAddress, bytes memory callData) internal {
        require(isContract(tokenAddress), "BAD_TOKEN_ADDRESS");
        // NOLINTNEXTLINE: low-level-calls.
        (bool success, bytes memory returndata) = tokenAddress.call(callData);
        require(success, string(returndata));

        if (returndata.length > 0) {
            require(abi.decode(returndata, (bool)), "TOKEN_OPERATION_FAILED");
        }
    }

    /*
      Validates that the passed contract address is of a real contract,
      and that its id hash (as infered fromn identify()) matched the expected one.
    */
    function validateContractId(address contractAddress, bytes32 expectedIdHash) internal {
        require(isContract(contractAddress), "ADDRESS_NOT_CONTRACT");
        (bool success, bytes memory returndata) = contractAddress.call( // NOLINT: low-level-calls.
            abi.encodeWithSignature("identify()")
        );
        require(success, "FAILED_TO_IDENTIFY_CONTRACT");
        string memory realContractId = abi.decode(returndata, (string));
        require(
            keccak256(abi.encodePacked(realContractId)) == expectedIdHash,
            "UNEXPECTED_CONTRACT_IDENTIFIER"
        );
    }
}

/*
  II. StarkExTypes - Common data types.
*/
library StarkExTypes {
    // Structure representing a list of verifiers (validity/availability).
    // A statement is valid only if all the verifiers in the list agree on it.
    // Adding a verifier to the list is immediate - this is used for fast resolution of
    // any soundness issues.
    // Removing from the list is time-locked, to ensure that any user of the system
    // not content with the announced removal has ample time to leave the system before it is
    // removed.
    struct ApprovalChainData {
        address[] list;
        // Represents the time after which the verifier with the given address can be removed.
        // Removal of the verifier with address A is allowed only in the case the value
        // of unlockedForRemovalTime[A] != 0 and unlockedForRemovalTime[A] < (current time).
        mapping(address => uint256) unlockedForRemovalTime;
    }
}

File 7 of 25 : MGovernance.sol
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

struct GovernanceInfoStruct {
    mapping(address => bool) effectiveGovernors;
    address candidateGovernor;
    bool initialized;
}

abstract contract MGovernance {
    function _isGovernor(address testGovernor) internal view virtual returns (bool);

    /*
      Allows calling the function only by a Governor.
    */
    modifier onlyGovernance() {
        require(_isGovernor(msg.sender), "ONLY_GOVERNANCE");
        _;
    }
}

File 8 of 25 : Freezable.sol
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

import "LibConstants.sol";
import "MFreezable.sol";
import "MGovernance.sol";
import "MainStorage.sol";

/*
  Implements MFreezable.
*/
abstract contract Freezable is MainStorage, LibConstants, MGovernance, MFreezable {
    event LogFrozen();
    event LogUnFrozen();

    function isFrozen() public view override returns (bool) {
        return stateFrozen;
    }

    function validateFreezeRequest(uint256 requestTime) internal override {
        require(requestTime != 0, "FORCED_ACTION_UNREQUESTED");
        // Verify timer on escape request.
        uint256 freezeTime = requestTime + FREEZE_GRACE_PERIOD;

        // Prevent wraparound.
        assert(freezeTime >= FREEZE_GRACE_PERIOD);
        require(block.timestamp >= freezeTime, "FORCED_ACTION_PENDING"); // NOLINT: timestamp.

        // Forced action requests placed before freeze, are no longer valid after the un-freeze.
        require(freezeTime > unFreezeTime, "REFREEZE_ATTEMPT");
    }

    function freeze() internal override notFrozen {
        unFreezeTime = block.timestamp + UNFREEZE_DELAY;

        // Update state.
        stateFrozen = true;

        // Log event.
        emit LogFrozen();
    }

    function unFreeze() external onlyFrozen onlyGovernance {
        require(block.timestamp >= unFreezeTime, "UNFREEZE_NOT_ALLOWED_YET");

        // Update state.
        stateFrozen = false;

        // Increment roots to invalidate them, w/o losing information.
        validiumVaultRoot += 1;
        rollupVaultRoot += 1;
        orderRoot += 1;

        // Log event.
        emit LogUnFrozen();
    }
}

File 9 of 25 : ProxyStorage.sol
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

import "GovernanceStorage.sol";

/*
  Holds the Proxy-specific state variables.
  This contract is inherited by the GovernanceStorage (and indirectly by MainStorage)
  to prevent collision hazard.
*/
contract ProxyStorage is GovernanceStorage {
    // NOLINTNEXTLINE: naming-convention uninitialized-state.
    mapping(address => bytes32) internal initializationHash_DEPRECATED;

    // The time after which we can switch to the implementation.
    // Hash(implementation, data, finalize) => time.
    mapping(bytes32 => uint256) internal enabledTime;

    // A central storage of the flags whether implementation has been initialized.
    // Note - it can be used flexibly enough to accommodate multiple levels of initialization
    // (i.e. using different key salting schemes for different initialization levels).
    mapping(bytes32 => bool) internal initialized;
}

File 10 of 25 : SubContractor.sol
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

import "Identity.sol";

interface SubContractor is Identity {
    function initialize(bytes calldata data) external;

    function initializerSize() external view returns (uint256);

    /*
      Returns an array with selectors for validation.
      These selectors are the critical ones for maintaining self custody and anti censorship.
      During the upgrade process, as part of the sub-contract validation, the MainDispatcher
      validates that the selectos are mapped to the correct sub-contract.
    */
    function validatedSelectors() external pure returns (bytes4[] memory);
}

File 11 of 25 : ECDSA.sol
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

import "EllipticCurve.sol";

library ECDSA {
    using EllipticCurve for uint256;
    uint256 constant FIELD_PRIME =
        0x800000000000011000000000000000000000000000000000000000000000001;
    uint256 constant ALPHA = 1;
    uint256 constant BETA =
        3141592653589793238462643383279502884197169399375105820974944592307816406665;
    uint256 constant EC_ORDER =
        3618502788666131213697322783095070105526743751716087489154079457884512865583;
    uint256 constant N_ELEMENT_BITS_ECDSA = 251;
    uint256 constant EC_GEN_X = 0x1ef15c18599971b7beced415a40f0c7deacfd9b0d1819e03d723d8bc943cfca;
    uint256 constant EC_GEN_Y = 0x5668060aa49730b7be4801df46ec62de53ecd11abe43a32873000c36e8dc1f;

    function verify(
        uint256 msgHash,
        uint256 r,
        uint256 s,
        uint256 pubX,
        uint256 pubY
    ) internal pure {
        require(msgHash % EC_ORDER == msgHash, "msgHash out of range");
        require((1 <= s) && (s < EC_ORDER), "s out of range");
        uint256 w = s.invMod(EC_ORDER);
        require((1 <= r) && (r < (1 << N_ELEMENT_BITS_ECDSA)), "r out of range");
        require((1 <= w) && (w < (1 << N_ELEMENT_BITS_ECDSA)), "w out of range");

        // Verify that pub is a valid point (y^2 = x^3 + x + BETA).
        {
            uint256 x3 = mulmod(mulmod(pubX, pubX, FIELD_PRIME), pubX, FIELD_PRIME);
            uint256 y2 = mulmod(pubY, pubY, FIELD_PRIME);
            require(
                y2 == addmod(addmod(x3, pubX, FIELD_PRIME), BETA, FIELD_PRIME),
                "INVALID_STARK_KEY"
            );
        }

        // Verify signature.
        uint256 b_x;
        uint256 b_y;
        {
            (uint256 zG_x, uint256 zG_y) = msgHash.ecMul(EC_GEN_X, EC_GEN_Y, ALPHA, FIELD_PRIME);

            (uint256 rQ_x, uint256 rQ_y) = r.ecMul(pubX, pubY, ALPHA, FIELD_PRIME);

            (b_x, b_y) = zG_x.ecAdd(zG_y, rQ_x, rQ_y, ALPHA, FIELD_PRIME);
        }
        (uint256 res_x, ) = w.ecMul(b_x, b_y, ALPHA, FIELD_PRIME);

        require(res_x == r, "INVALID_STARK_SIGNATURE");
    }
}

File 12 of 25 : MKeyGetters.sol
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

abstract contract MKeyGetters {
    // NOLINTNEXTLINE: external-function.
    function getEthKey(uint256 ownerKey) public view virtual returns (address);

    function strictGetEthKey(uint256 ownerKey) internal view virtual returns (address);

    function isMsgSenderKeyOwner(uint256 ownerKey) internal view virtual returns (bool);

    /*
      Allows calling the function only if ownerKey is registered to msg.sender.
    */
    modifier onlyKeyOwner(uint256 ownerKey) {
        // Require the calling user to own the stark key.
        require(msg.sender == strictGetEthKey(ownerKey), "MISMATCHING_STARK_ETH_KEYS");
        _;
    }
}

File 13 of 25 : EllipticCurve.sol
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: MIT.
/*
  MIT License

  Copyright (c) 2019 Witnet Project

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  SOFTWARE.
*/
// https://github.com/witnet/elliptic-curve-solidity/blob/master/contracts/EllipticCurve.sol
pragma solidity >=0.5.3 <0.7.0; // NOLINT pragma.

/**
 * @title Elliptic Curve Library
 * @dev Library providing arithmetic operations over elliptic curves.
 * This library does not check whether the inserted points belong to the curve
 * `isOnCurve` function should be used by the library user to check the aforementioned statement.
 * @author Witnet Foundation
 */
library EllipticCurve {

  // Pre-computed constant for 2 ** 255
  uint256 constant private U255_MAX_PLUS_1 = 57896044618658097711785492504343953926634992332820282019728792003956564819968;

  /// @dev Modular euclidean inverse of a number (mod p).
  /// @param _x The number
  /// @param _pp The modulus
  /// @return q such that x*q = 1 (mod _pp)
  function invMod(uint256 _x, uint256 _pp) internal pure returns (uint256) {
    require(_x != 0 && _x != _pp && _pp != 0, "Invalid number");
    uint256 q = 0;
    uint256 newT = 1;
    uint256 r = _pp;
    uint256 t;
    while (_x != 0) {
      t = r / _x;
      (q, newT) = (newT, addmod(q, (_pp - mulmod(t, newT, _pp)), _pp));
      (r, _x) = (_x, r - t * _x);
    }

    return q;
  }

  /// @dev Modular exponentiation, b^e % _pp.
  /// Source: https://github.com/androlo/standard-contracts/blob/master/contracts/src/crypto/ECCMath.sol
  /// @param _base base
  /// @param _exp exponent
  /// @param _pp modulus
  /// @return r such that r = b**e (mod _pp)
  function expMod(uint256 _base, uint256 _exp, uint256 _pp) internal pure returns (uint256) {
    require(_pp!=0, "Modulus is zero");

    if (_base == 0)
      return 0;
    if (_exp == 0)
      return 1;

    uint256 r = 1;
    uint256 bit = U255_MAX_PLUS_1;
    assembly {
      for { } gt(bit, 0) { }{
        r := mulmod(mulmod(r, r, _pp), exp(_base, iszero(iszero(and(_exp, bit)))), _pp)
        r := mulmod(mulmod(r, r, _pp), exp(_base, iszero(iszero(and(_exp, div(bit, 2))))), _pp)
        r := mulmod(mulmod(r, r, _pp), exp(_base, iszero(iszero(and(_exp, div(bit, 4))))), _pp)
        r := mulmod(mulmod(r, r, _pp), exp(_base, iszero(iszero(and(_exp, div(bit, 8))))), _pp)
        bit := div(bit, 16)
      }
    }

    return r;
  }

  /// @dev Converts a point (x, y, z) expressed in Jacobian coordinates to affine coordinates (x', y', 1).
  /// @param _x coordinate x
  /// @param _y coordinate y
  /// @param _z coordinate z
  /// @param _pp the modulus
  /// @return (x', y') affine coordinates
  function toAffine(
    uint256 _x,
    uint256 _y,
    uint256 _z,
    uint256 _pp)
  internal pure returns (uint256, uint256)
  {
    uint256 zInv = invMod(_z, _pp);
    uint256 zInv2 = mulmod(zInv, zInv, _pp);
    uint256 x2 = mulmod(_x, zInv2, _pp);
    uint256 y2 = mulmod(_y, mulmod(zInv, zInv2, _pp), _pp);

    return (x2, y2);
  }

  /// @dev Derives the y coordinate from a compressed-format point x [[SEC-1]](https://www.secg.org/SEC1-Ver-1.0.pdf).
  /// @param _prefix parity byte (0x02 even, 0x03 odd)
  /// @param _x coordinate x
  /// @param _aa constant of curve
  /// @param _bb constant of curve
  /// @param _pp the modulus
  /// @return y coordinate y
  function deriveY(
    uint8 _prefix,
    uint256 _x,
    uint256 _aa,
    uint256 _bb,
    uint256 _pp)
  internal pure returns (uint256)
  {
    require(_prefix == 0x02 || _prefix == 0x03, "Invalid compressed EC point prefix");

    // x^3 + ax + b
    uint256 y2 = addmod(mulmod(_x, mulmod(_x, _x, _pp), _pp), addmod(mulmod(_x, _aa, _pp), _bb, _pp), _pp);
    y2 = expMod(y2, (_pp + 1) / 4, _pp);
    // uint256 cmp = yBit ^ y_ & 1;
    uint256 y = (y2 + _prefix) % 2 == 0 ? y2 : _pp - y2;

    return y;
  }

  /// @dev Check whether point (x,y) is on curve defined by a, b, and _pp.
  /// @param _x coordinate x of P1
  /// @param _y coordinate y of P1
  /// @param _aa constant of curve
  /// @param _bb constant of curve
  /// @param _pp the modulus
  /// @return true if x,y in the curve, false else
  function isOnCurve(
    uint _x,
    uint _y,
    uint _aa,
    uint _bb,
    uint _pp)
  internal pure returns (bool)
  {
    if (0 == _x || _x >= _pp || 0 == _y || _y >= _pp) {
      return false;
    }
    // y^2
    uint lhs = mulmod(_y, _y, _pp);
    // x^3
    uint rhs = mulmod(mulmod(_x, _x, _pp), _x, _pp);
    if (_aa != 0) {
      // x^3 + a*x
      rhs = addmod(rhs, mulmod(_x, _aa, _pp), _pp);
    }
    if (_bb != 0) {
      // x^3 + a*x + b
      rhs = addmod(rhs, _bb, _pp);
    }

    return lhs == rhs;
  }

  /// @dev Calculate inverse (x, -y) of point (x, y).
  /// @param _x coordinate x of P1
  /// @param _y coordinate y of P1
  /// @param _pp the modulus
  /// @return (x, -y)
  function ecInv(
    uint256 _x,
    uint256 _y,
    uint256 _pp)
  internal pure returns (uint256, uint256)
  {
    return (_x, (_pp - _y) % _pp);
  }

  /// @dev Add two points (x1, y1) and (x2, y2) in affine coordinates.
  /// @param _x1 coordinate x of P1
  /// @param _y1 coordinate y of P1
  /// @param _x2 coordinate x of P2
  /// @param _y2 coordinate y of P2
  /// @param _aa constant of the curve
  /// @param _pp the modulus
  /// @return (qx, qy) = P1+P2 in affine coordinates
  function ecAdd(
    uint256 _x1,
    uint256 _y1,
    uint256 _x2,
    uint256 _y2,
    uint256 _aa,
    uint256 _pp)
    internal pure returns(uint256, uint256)
  {
    uint x = 0;
    uint y = 0;
    uint z = 0;

    // Double if x1==x2 else add
    if (_x1==_x2) {
      // y1 = -y2 mod p
      if (addmod(_y1, _y2, _pp) == 0) {
        return(0, 0);
      } else {
        // P1 = P2
        (x, y, z) = jacDouble(
          _x1,
          _y1,
          1,
          _aa,
          _pp);
      }
    } else {
      (x, y, z) = jacAdd(
        _x1,
        _y1,
        1,
        _x2,
        _y2,
        1,
        _pp);
    }
    // Get back to affine
    return toAffine(
      x,
      y,
      z,
      _pp);
  }

  /// @dev Substract two points (x1, y1) and (x2, y2) in affine coordinates.
  /// @param _x1 coordinate x of P1
  /// @param _y1 coordinate y of P1
  /// @param _x2 coordinate x of P2
  /// @param _y2 coordinate y of P2
  /// @param _aa constant of the curve
  /// @param _pp the modulus
  /// @return (qx, qy) = P1-P2 in affine coordinates
  function ecSub(
    uint256 _x1,
    uint256 _y1,
    uint256 _x2,
    uint256 _y2,
    uint256 _aa,
    uint256 _pp)
  internal pure returns(uint256, uint256)
  {
    // invert square
    (uint256 x, uint256 y) = ecInv(_x2, _y2, _pp);
    // P1-square
    return ecAdd(
      _x1,
      _y1,
      x,
      y,
      _aa,
      _pp);
  }

  /// @dev Multiply point (x1, y1, z1) times d in affine coordinates.
  /// @param _k scalar to multiply
  /// @param _x coordinate x of P1
  /// @param _y coordinate y of P1
  /// @param _aa constant of the curve
  /// @param _pp the modulus
  /// @return (qx, qy) = d*P in affine coordinates
  function ecMul(
    uint256 _k,
    uint256 _x,
    uint256 _y,
    uint256 _aa,
    uint256 _pp)
  internal pure returns(uint256, uint256)
  {
    // Jacobian multiplication
    (uint256 x1, uint256 y1, uint256 z1) = jacMul(
      _k,
      _x,
      _y,
      1,
      _aa,
      _pp);
    // Get back to affine
    return toAffine(
      x1,
      y1,
      z1,
      _pp);
  }

  /// @dev Adds two points (x1, y1, z1) and (x2 y2, z2).
  /// @param _x1 coordinate x of P1
  /// @param _y1 coordinate y of P1
  /// @param _z1 coordinate z of P1
  /// @param _x2 coordinate x of square
  /// @param _y2 coordinate y of square
  /// @param _z2 coordinate z of square
  /// @param _pp the modulus
  /// @return (qx, qy, qz) P1+square in Jacobian
  function jacAdd(
    uint256 _x1,
    uint256 _y1,
    uint256 _z1,
    uint256 _x2,
    uint256 _y2,
    uint256 _z2,
    uint256 _pp)
  internal pure returns (uint256, uint256, uint256)
  {
    if (_x1==0 && _y1==0)
      return (_x2, _y2, _z2);
    if (_x2==0 && _y2==0)
      return (_x1, _y1, _z1);

    // We follow the equations described in https://pdfs.semanticscholar.org/5c64/29952e08025a9649c2b0ba32518e9a7fb5c2.pdf Section 5
    uint[4] memory zs; // z1^2, z1^3, z2^2, z2^3
    zs[0] = mulmod(_z1, _z1, _pp);
    zs[1] = mulmod(_z1, zs[0], _pp);
    zs[2] = mulmod(_z2, _z2, _pp);
    zs[3] = mulmod(_z2, zs[2], _pp);

    // u1, s1, u2, s2
    zs = [
      mulmod(_x1, zs[2], _pp),
      mulmod(_y1, zs[3], _pp),
      mulmod(_x2, zs[0], _pp),
      mulmod(_y2, zs[1], _pp)
    ];

    // In case of zs[0] == zs[2] && zs[1] == zs[3], double function should be used
    require(zs[0] != zs[2] || zs[1] != zs[3], "Use jacDouble function instead");

    uint[4] memory hr;
    //h
    hr[0] = addmod(zs[2], _pp - zs[0], _pp);
    //r
    hr[1] = addmod(zs[3], _pp - zs[1], _pp);
    //h^2
    hr[2] = mulmod(hr[0], hr[0], _pp);
    // h^3
    hr[3] = mulmod(hr[2], hr[0], _pp);
    // qx = -h^3  -2u1h^2+r^2
    uint256 qx = addmod(mulmod(hr[1], hr[1], _pp), _pp - hr[3], _pp);
    qx = addmod(qx, _pp - mulmod(2, mulmod(zs[0], hr[2], _pp), _pp), _pp);
    // qy = -s1*z1*h^3+r(u1*h^2 -x^3)
    uint256 qy = mulmod(hr[1], addmod(mulmod(zs[0], hr[2], _pp), _pp - qx, _pp), _pp);
    qy = addmod(qy, _pp - mulmod(zs[1], hr[3], _pp), _pp);
    // qz = h*z1*z2
    uint256 qz = mulmod(hr[0], mulmod(_z1, _z2, _pp), _pp);
    return(qx, qy, qz);
  }

  /// @dev Doubles a points (x, y, z).
  /// @param _x coordinate x of P1
  /// @param _y coordinate y of P1
  /// @param _z coordinate z of P1
  /// @param _aa the a scalar in the curve equation
  /// @param _pp the modulus
  /// @return (qx, qy, qz) 2P in Jacobian
  function jacDouble(
    uint256 _x,
    uint256 _y,
    uint256 _z,
    uint256 _aa,
    uint256 _pp)
  internal pure returns (uint256, uint256, uint256)
  {
    if (_z == 0)
      return (_x, _y, _z);

    // We follow the equations described in https://pdfs.semanticscholar.org/5c64/29952e08025a9649c2b0ba32518e9a7fb5c2.pdf Section 5
    // Note: there is a bug in the paper regarding the m parameter, M=3*(x1^2)+a*(z1^4)
    // x, y, z at this point represent the squares of _x, _y, _z
    uint256 x = mulmod(_x, _x, _pp); //x1^2
    uint256 y = mulmod(_y, _y, _pp); //y1^2
    uint256 z = mulmod(_z, _z, _pp); //z1^2

    // s
    uint s = mulmod(4, mulmod(_x, y, _pp), _pp);
    // m
    uint m = addmod(mulmod(3, x, _pp), mulmod(_aa, mulmod(z, z, _pp), _pp), _pp);

    // x, y, z at this point will be reassigned and rather represent qx, qy, qz from the paper
    // This allows to reduce the gas cost and stack footprint of the algorithm
    // qx
    x = addmod(mulmod(m, m, _pp), _pp - addmod(s, s, _pp), _pp);
    // qy = -8*y1^4 + M(S-T)
    y = addmod(mulmod(m, addmod(s, _pp - x, _pp), _pp), _pp - mulmod(8, mulmod(y, y, _pp), _pp), _pp);
    // qz = 2*y1*z1
    z = mulmod(2, mulmod(_y, _z, _pp), _pp);

    return (x, y, z);
  }

  /// @dev Multiply point (x, y, z) times d.
  /// @param _d scalar to multiply
  /// @param _x coordinate x of P1
  /// @param _y coordinate y of P1
  /// @param _z coordinate z of P1
  /// @param _aa constant of curve
  /// @param _pp the modulus
  /// @return (qx, qy, qz) d*P1 in Jacobian
  function jacMul(
    uint256 _d,
    uint256 _x,
    uint256 _y,
    uint256 _z,
    uint256 _aa,
    uint256 _pp)
  internal pure returns (uint256, uint256, uint256)
  {
    // Early return in case that `_d == 0`
    if (_d == 0) {
      return (_x, _y, _z);
    }

    uint256 remaining = _d;
    uint256 qx = 0;
    uint256 qy = 0;
    uint256 qz = 1;

    // Double and add algorithm
    while (remaining != 0) {
      if ((remaining & 1) != 0) {
        (qx, qy, qz) = jacAdd(
          qx,
          qy,
          qz,
          _x,
          _y,
          _z,
          _pp);
      }
      remaining = remaining / 2;
      (_x, _y, _z) = jacDouble(
        _x,
        _y,
        _z,
        _aa,
        _pp);
    }
    return (qx, qy, qz);
  }
}

File 14 of 25 : MFreezable.sol
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

abstract contract MFreezable {
    /*
      Returns true if the exchange is frozen.
    */
    function isFrozen() public view virtual returns (bool); // NOLINT: external-function.

    /*
      Forbids calling the function if the exchange is frozen.
    */
    modifier notFrozen() {
        require(!isFrozen(), "STATE_IS_FROZEN");
        _;
    }

    function validateFreezeRequest(uint256 requestTime) internal virtual;

    /*
      Allows calling the function only if the exchange is frozen.
    */
    modifier onlyFrozen() {
        require(isFrozen(), "STATE_NOT_FROZEN");
        _;
    }

    /*
      Freezes the exchange.
    */
    function freeze() internal virtual;
}

File 15 of 25 : FullWithdrawals.sol
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

import "MStarkExForcedActionState.sol";
import "StateRoot.sol";
import "MFreezable.sol";
import "MKeyGetters.sol";

/**
  At any point in time, a user may opt to perform a full withdrawal request for a given off-chain
  vault. Such a request is a different flow than the normal withdrawal flow
  (see :sol:mod:`Withdrawals`) in the following ways:

  1. The user calls a contract function instead of calling an off-chain service API.
  2. Upon the successful fulfillment of the operation, the entire vault balance is withdrawn, and it is effectively evicted (no longer belongs to the user). Hence, a full withdrawal request does not include an amount to withdraw.
  3. Failure of the offchain exchange to service a full withdrawal request within a given timeframe gives the user the option to freeze the exchange disabling the ability to update its state.

  A full withdrawal operation is executed as follows:

  1. The user submits a full withdrawal request by calling :sol:func:`fullWithdrawalRequest` with the vault ID to be withdrawn.
  2. Under normal operation of the exchange service, the exchange submits a STARK proof indicating the fulfillment of the withdrawal from the vault.
  3. If the exchange fails to service the request (does not submit a valid proof as above), upon the expiration of a :sol:cons:`FREEZE_GRACE_PERIOD`, the user is entitled to freeze the contract by calling :sol:func:`freezeRequest` and indicating the vaultId for which the full withdrawal request has not been serviced.
  4. Upon acceptance of the proof above, the contract adds the withdrawn amount to an on-chain pending withdrawals account under the stark key of the vault owner and the appropriate asset ID. At the same time, the full withdrawal request is cleared.
  5. The user may then withdraw this amount from the pending withdrawals account by calling the normal withdraw function (see :sol:mod:`Withdrawals`) to transfer the funds to the users Eth or ERC20 account (depending on the token type).

  If a user requests a full withdrawal for a vault that is not associated with the ownerKey of the
  user, the exchange may prove this and the full withdrawal request is cleared without any effect on
  the vault (and no funds will be released on-chain for withdrawal).

  Full withdrawal requests cannot be cancelled by a user.

  To avoid the potential attack of the exchange by a flood of full withdrawal requests, the rate of
  such requests must be limited. In the currently implementation, this is achieved by making the
  cost of the request exceed 1M gas.

*/
abstract contract FullWithdrawals is StateRoot, MStarkExForcedActionState, MFreezable, MKeyGetters {
    event LogFullWithdrawalRequest(uint256 ownerKey, uint256 vaultId);

    function fullWithdrawalRequest(uint256 ownerKey, uint256 vaultId)
        external
        notFrozen
        onlyKeyOwner(ownerKey)
    {
        // Verify vault ID in range.
        require(isVaultInRange(vaultId), "OUT_OF_RANGE_VAULT_ID");

        // Start timer on escape request.
        setFullWithdrawalRequest(ownerKey, vaultId);

        // Log request.
        emit LogFullWithdrawalRequest(ownerKey, vaultId);
    }

    function freezeRequest(uint256 ownerKey, uint256 vaultId) external notFrozen {
        // Verify vaultId in range.
        require(isVaultInRange(vaultId), "OUT_OF_RANGE_VAULT_ID");

        // Load request time.
        uint256 requestTime = getFullWithdrawalRequest(ownerKey, vaultId);

        validateFreezeRequest(requestTime);
        freeze();
    }
}

File 16 of 25 : StateRoot.sol
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

import "MStateRoot.sol";
import "MainStorage.sol";
import "LibConstants.sol";

contract StateRoot is MainStorage, LibConstants, MStateRoot {
    function initialize(
        uint256 initialSequenceNumber,
        uint256 initialValidiumVaultRoot,
        uint256 initialRollupVaultRoot,
        uint256 initialOrderRoot,
        uint256 initialValidiumTreeHeight,
        uint256 initialRollupTreeHeight,
        uint256 initialOrderTreeHeight
    ) internal {
        sequenceNumber = initialSequenceNumber;
        validiumVaultRoot = initialValidiumVaultRoot;
        rollupVaultRoot = initialRollupVaultRoot;
        orderRoot = initialOrderRoot;
        validiumTreeHeight = initialValidiumTreeHeight;
        rollupTreeHeight = initialRollupTreeHeight;
        orderTreeHeight = initialOrderTreeHeight;
    }

    function getValidiumVaultRoot() public view override returns (uint256) {
        return validiumVaultRoot;
    }

    function getValidiumTreeHeight() public view override returns (uint256) {
        return validiumTreeHeight;
    }

    function getRollupVaultRoot() public view override returns (uint256) {
        return rollupVaultRoot;
    }

    function getRollupTreeHeight() public view override returns (uint256) {
        return rollupTreeHeight;
    }

    function getOrderRoot() external view returns (uint256) {
        return orderRoot;
    }

    function getOrderTreeHeight() external view returns (uint256) {
        return orderTreeHeight;
    }

    function getSequenceNumber() external view returns (uint256) {
        return sequenceNumber;
    }

    function getLastBatchId() external view returns (uint256) {
        return lastBatchId;
    }

    function getGlobalConfigCode() external view returns (uint256) {
        return globalConfigCode;
    }

    function isVaultInRange(uint256 vaultId) internal view override returns (bool) {
        return (isValidiumVault(vaultId) || isRollupVault(vaultId));
    }

    function isValidiumVault(uint256 vaultId) internal view override returns (bool) {
        // Return true iff vaultId is in the validium vaults tree.
        return vaultId < 2**getValidiumTreeHeight();
    }

    function isRollupVault(uint256 vaultId) internal view override returns (bool) {
        // Return true iff vaultId is in the rollup vaults tree.
        uint256 rollupLowerBound = 2**ROLLUP_VAULTS_BIT;
        uint256 rollupUpperBound = rollupLowerBound + 2**getRollupTreeHeight();
        return (rollupLowerBound <= vaultId && vaultId < rollupUpperBound);
    }

    function getVaultLeafIndex(uint256 vaultId) internal pure override returns (uint256) {
        // Return the index of vaultId leaf in its tree, which doesn't include the rollup bit flag.
        return (vaultId & (2**ROLLUP_VAULTS_BIT - 1));
    }
}

File 17 of 25 : Governance.sol
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

import "MGovernance.sol";

/*
  Implements Generic Governance, applicable for both proxy and main contract, and possibly others.
  Notes:
   The use of the same function names by both the Proxy and a delegated implementation
   is not possible since calling the implementation functions is done via the default function
   of the Proxy. For this reason, for example, the implementation of MainContract (MainGovernance)
   exposes mainIsGovernor, which calls the internal _isGovernor method.
*/
abstract contract Governance is MGovernance {
    event LogNominatedGovernor(address nominatedGovernor);
    event LogNewGovernorAccepted(address acceptedGovernor);
    event LogRemovedGovernor(address removedGovernor);
    event LogNominationCancelled();

    function getGovernanceInfo() internal view virtual returns (GovernanceInfoStruct storage);

    /*
      Current code intentionally prevents governance re-initialization.
      This may be a problem in an upgrade situation, in a case that the upgrade-to implementation
      performs an initialization (for real) and within that calls initGovernance().

      Possible workarounds:
      1. Clearing the governance info altogether by changing the MAIN_GOVERNANCE_INFO_TAG.
         This will remove existing main governance information.
      2. Modify the require part in this function, so that it will exit quietly
         when trying to re-initialize (uncomment the lines below).
    */
    function initGovernance() internal {
        GovernanceInfoStruct storage gub = getGovernanceInfo();
        require(!gub.initialized, "ALREADY_INITIALIZED");
        gub.initialized = true; // to ensure addGovernor() won't fail.
        // Add the initial governer.
        addGovernor(msg.sender);
    }

    function _isGovernor(address testGovernor) internal view override returns (bool) {
        GovernanceInfoStruct storage gub = getGovernanceInfo();
        return gub.effectiveGovernors[testGovernor];
    }

    /*
      Cancels the nomination of a governor candidate.
    */
    function _cancelNomination() internal onlyGovernance {
        GovernanceInfoStruct storage gub = getGovernanceInfo();
        gub.candidateGovernor = address(0x0);
        emit LogNominationCancelled();
    }

    function _nominateNewGovernor(address newGovernor) internal onlyGovernance {
        GovernanceInfoStruct storage gub = getGovernanceInfo();
        require(!_isGovernor(newGovernor), "ALREADY_GOVERNOR");
        gub.candidateGovernor = newGovernor;
        emit LogNominatedGovernor(newGovernor);
    }

    /*
      The addGovernor is called in two cases:
      1. by _acceptGovernance when a new governor accepts its role.
      2. by initGovernance to add the initial governor.
      The difference is that the init path skips the nominate step
      that would fail because of the onlyGovernance modifier.
    */
    function addGovernor(address newGovernor) private {
        require(!_isGovernor(newGovernor), "ALREADY_GOVERNOR");
        GovernanceInfoStruct storage gub = getGovernanceInfo();
        gub.effectiveGovernors[newGovernor] = true;
    }

    function _acceptGovernance() internal {
        // The new governor was proposed as a candidate by the current governor.
        GovernanceInfoStruct storage gub = getGovernanceInfo();
        require(msg.sender == gub.candidateGovernor, "ONLY_CANDIDATE_GOVERNOR");

        // Update state.
        addGovernor(gub.candidateGovernor);
        gub.candidateGovernor = address(0x0);

        // Send a notification about the change of governor.
        emit LogNewGovernorAccepted(msg.sender);
    }

    /*
      Remove a governor from office.
    */
    function _removeGovernor(address governorForRemoval) internal onlyGovernance {
        require(msg.sender != governorForRemoval, "GOVERNOR_SELF_REMOVE");
        GovernanceInfoStruct storage gub = getGovernanceInfo();
        require(_isGovernor(governorForRemoval), "NOT_GOVERNOR");
        gub.effectiveGovernors[governorForRemoval] = false;
        emit LogRemovedGovernor(governorForRemoval);
    }
}

File 18 of 25 : ActionHash.sol
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

import "MainStorage.sol";
import "LibConstants.sol";

/*
  Calculation action hash for the various forced actions in a generic manner.
*/
contract ActionHash is MainStorage, LibConstants {
    function getActionHash(string memory actionName, bytes memory packedActionParameters)
        internal
        pure
        returns (bytes32 actionHash)
    {
        actionHash = keccak256(abi.encodePacked(actionName, packedActionParameters));
    }

    function setActionHash(bytes32 actionHash, bool premiumCost) internal {
        // The rate of forced trade requests is restricted.
        // First restriction is by capping the number of requests in a block.
        // User can override this cap by requesting with a permium flag set,
        // in this case, the gas cost is high (~1M) but no "technical" limit is set.
        // However, the high gas cost creates an obvious limitation due to the block gas limit.
        if (premiumCost) {
            for (uint256 i = 0; i < 21129; i++) {}
        } else {
            require(
                forcedRequestsInBlock[block.number] < MAX_FORCED_ACTIONS_REQS_PER_BLOCK,
                "MAX_REQUESTS_PER_BLOCK_REACHED"
            );
            forcedRequestsInBlock[block.number] += 1;
        }
        forcedActionRequests[actionHash] = block.timestamp;
        actionHashList.push(actionHash);
    }

    function getActionCount() external view returns (uint256) {
        return actionHashList.length;
    }

    function getActionHashByIndex(uint256 actionIndex) external view returns (bytes32) {
        require(actionIndex < actionHashList.length, "ACTION_INDEX_TOO_HIGH");
        return actionHashList[actionIndex];
    }
}

File 19 of 25 : LibConstants.sol
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

contract LibConstants {
    // Durations for time locked mechanisms (in seconds).
    // Note that it is known that miners can manipulate block timestamps
    // up to a deviation of a few seconds.
    // This mechanism should not be used for fine grained timing.

    // The time required to cancel a deposit, in the case the operator does not move the funds
    // to the off-chain storage.
    uint256 public constant DEPOSIT_CANCEL_DELAY = 2 days;

    // The time required to freeze the exchange, in the case the operator does not execute a
    // requested full withdrawal.
    uint256 public constant FREEZE_GRACE_PERIOD = 7 days;

    // The time after which the exchange may be unfrozen after it froze. This should be enough time
    // for users to perform escape hatches to get back their funds.
    uint256 public constant UNFREEZE_DELAY = 365 days;

    // Maximal number of verifiers which may co-exist.
    uint256 public constant MAX_VERIFIER_COUNT = uint256(64);

    // The time required to remove a verifier in case of a verifier upgrade.
    uint256 public constant VERIFIER_REMOVAL_DELAY = FREEZE_GRACE_PERIOD + (21 days);

    address constant ZERO_ADDRESS = address(0x0);

    uint256 constant K_MODULUS = 0x800000000000011000000000000000000000000000000000000000000000001;

    uint256 constant K_BETA = 0x6f21413efbe40de150e596d72f7a8c5609ad26c15c915c1f4cdfcb99cee9e89;

    uint256 internal constant MASK_250 =
        0x03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
    uint256 internal constant MASK_240 =
        0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

    uint256 public constant MAX_FORCED_ACTIONS_REQS_PER_BLOCK = 10;

    uint256 constant QUANTUM_UPPER_BOUND = 2**128;
    uint256 internal constant MINTABLE_ASSET_ID_FLAG = 1 << 250;

    // The 64th bit (indexed 63, counting from 0) is a flag indicating a rollup vault id.
    uint256 constant ROLLUP_VAULTS_BIT = 63;
}

File 20 of 25 : MainGovernance.sol
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

import "Governance.sol";
import "GovernanceStorage.sol";

/**
  The StarkEx contract is governed by one or more Governors of which the initial one is the
  deployer of the contract.

  A governor has the sole authority to perform the following operations:

  1. Nominate additional governors (:sol:func:`mainNominateNewGovernor`)
  2. Remove other governors (:sol:func:`mainRemoveGovernor`)
  3. Add new :sol:mod:`Verifiers` and :sol:mod:`AvailabilityVerifiers`
  4. Remove :sol:mod:`Verifiers` and :sol:mod:`AvailabilityVerifiers` after a timelock allows it
  5. Nominate Operators (see :sol:mod:`Operator`) and Token Administrators (see :sol:mod:`TokenRegister`)

  Adding governors is performed in a two step procedure:

  1. First, an existing governor nominates a new governor (:sol:func:`mainNominateNewGovernor`)
  2. Then, the new governor must accept governance to become a governor (:sol:func:`mainAcceptGovernance`)

  This two step procedure ensures that a governor public key cannot be nominated unless there is an
  entity that has the corresponding private key. This is intended to prevent errors in the addition
  process.

  The governor private key should typically be held in a secure cold wallet.
*/
/*
  Implements Governance for the StarkDex main contract.
  The wrapper methods (e.g. mainIsGovernor wrapping _isGovernor) are needed to give
  the method unique names.
  Both Proxy and StarkExchange inherit from Governance. Thus, the logical contract method names
  must have unique names in order for the proxy to successfully delegate to them.
*/
contract MainGovernance is GovernanceStorage, Governance {
    // The tag is the sting key that is used in the Governance storage mapping.
    string public constant MAIN_GOVERNANCE_INFO_TAG = "StarkEx.Main.2019.GovernorsInformation";

    /*
      Returns the GovernanceInfoStruct associated with the governance tag.
    */
    function getGovernanceInfo() internal view override returns (GovernanceInfoStruct storage) {
        return governanceInfo[MAIN_GOVERNANCE_INFO_TAG];
    }

    function mainIsGovernor(address testGovernor) external view returns (bool) {
        return _isGovernor(testGovernor);
    }

    function mainNominateNewGovernor(address newGovernor) external {
        _nominateNewGovernor(newGovernor);
    }

    function mainRemoveGovernor(address governorForRemoval) external {
        _removeGovernor(governorForRemoval);
    }

    function mainAcceptGovernance() external {
        _acceptGovernance();
    }

    function mainCancelNomination() external {
        _cancelNomination();
    }
}

File 21 of 25 : StarkExForcedActionState.sol
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

import "StarkExStorage.sol";
import "MStarkExForcedActionState.sol";
import "ActionHash.sol";

/*
  StarkExchange specific action hashses.
*/
contract StarkExForcedActionState is StarkExStorage, ActionHash, MStarkExForcedActionState {
    function fullWithdrawActionHash(uint256 ownerKey, uint256 vaultId)
        internal
        pure
        override
        returns (bytes32)
    {
        return getActionHash("FULL_WITHDRAWAL", abi.encode(ownerKey, vaultId));
    }

    /*
      Implemented in the FullWithdrawal contracts.
    */
    function clearFullWithdrawalRequest(uint256 ownerKey, uint256 vaultId)
        internal
        virtual
        override
    {
        // Reset escape request.
        delete forcedActionRequests[fullWithdrawActionHash(ownerKey, vaultId)];
    }

    function getFullWithdrawalRequest(uint256 ownerKey, uint256 vaultId)
        public
        view
        override
        returns (uint256)
    {
        // Return request value. Expect zero if the request doesn't exist or has been serviced, and
        // a non-zero value otherwise.
        return forcedActionRequests[fullWithdrawActionHash(ownerKey, vaultId)];
    }

    function setFullWithdrawalRequest(uint256 ownerKey, uint256 vaultId) internal override {
        // FullWithdrawal is always at premium cost, hence the `true`.
        setActionHash(fullWithdrawActionHash(ownerKey, vaultId), true);
    }
}

File 22 of 25 : Identity.sol
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

interface Identity {
    /*
      Allows a caller, typically another contract,
      to ensure that the provided address is of the expected type and version.
    */
    function identify() external pure returns (string memory);
}

File 23 of 25 : MStateRoot.sol
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

abstract contract MStateRoot {
    function getValidiumVaultRoot() public view virtual returns (uint256);

    function getValidiumTreeHeight() public view virtual returns (uint256);

    function getRollupVaultRoot() public view virtual returns (uint256);

    function getRollupTreeHeight() public view virtual returns (uint256);

    /*
      Returns true iff vaultId is in the valid vault ids range,
      i.e. could appear in either the validium or rollup vaults trees.
    */
    function isVaultInRange(uint256 vaultId) internal view virtual returns (bool);

    /*
      Returns true if vaultId is a valid validium vault id.

      Note: when this function returns false it might mean that vaultId is invalid and does not
      guarantee that vaultId is a valid rollup vault id.
    */
    function isValidiumVault(uint256 vaultId) internal view virtual returns (bool);

    /*
      Returns true if vaultId is a valid rollup vault id.

      Note: when this function returns false it might mean that vaultId is invalid and does not
      guarantee that vaultId is a valid validium vault id.
    */
    function isRollupVault(uint256 vaultId) internal view virtual returns (bool);

    /*
      Given a valid vaultId, returns its leaf index in the validium/rollup tree.

      Note: this function does not assert the validity of vaultId, make sure to explicitly assert it
      when required.
    */
    function getVaultLeafIndex(uint256 vaultId) internal pure virtual returns (uint256);
}

File 24 of 25 : MStarkExForcedActionState.sol
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

abstract contract MStarkExForcedActionState {
    function fullWithdrawActionHash(uint256 ownerKey, uint256 vaultId)
        internal
        pure
        virtual
        returns (bytes32);

    function clearFullWithdrawalRequest(uint256 ownerKey, uint256 vaultId) internal virtual;

    // NOLINTNEXTLINE: external-function.
    function getFullWithdrawalRequest(uint256 ownerKey, uint256 vaultId)
        public
        view
        virtual
        returns (uint256);

    function setFullWithdrawalRequest(uint256 ownerKey, uint256 vaultId) internal virtual;
}

File 25 of 25 : StarkExStorage.sol
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

import "MainStorage.sol";

/*
  Extends MainStorage, holds StarkEx App specific state (storage) variables.

  ALL State variables that are common to all applications, reside in MainStorage,
  whereas ALL the StarkEx app specific ones reside here.
*/
contract StarkExStorage is MainStorage {
    // Onchain vaults balances.
    // A map eth_address => asset_id => vault_id => quantized amount.
    mapping(address => mapping(uint256 => mapping(uint256 => uint256))) vaultsBalances;

    // Onchain vaults withdrawal lock time.
    // A map eth_address => asset_id => vault_id => lock expiration timestamp.
    mapping(address => mapping(uint256 => mapping(uint256 => uint256))) vaultsWithdrawalLocks;

    // Enforces the minimal balance requirement (as output by Cairo) on onchain vault updates.
    // When disabled, flash loans are enabled.
    bool strictVaultBalancePolicy; // NOLINT: constable-states, uninitialized-state.

    // The default time, in seconds, that an onchain vault is locked for withdrawal after a deposit.
    uint256 public defaultVaultWithdrawalLock; // NOLINT: constable-states.

    // Address of the message registry contract that is used to sign and verify L1 orders.
    address public orderRegistryAddress; // NOLINT: constable-states.

    // Reserved storage space for Extensibility.
    // Every added MUST be added above the end gap, and the __endGap size must be reduced
    // accordingly.
    // NOLINTNEXTLINE: naming-convention shadowing-abstract.
    uint256[LAYOUT_LENGTH - 5] private __endGap; // __endGap complements layout to LAYOUT_LENGTH.
}

Settings
{
  "metadata": {
    "useLiteralContent": true
  },
  "libraries": {},
  "remappings": [],
  "optimizer": {
    "enabled": true,
    "runs": 100
  },
  "evmVersion": "istanbul",
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[],"name":"LogFrozen","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"ownerKey","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"vaultId","type":"uint256"}],"name":"LogFullWithdrawalRequest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"acceptedGovernor","type":"address"}],"name":"LogNewGovernorAccepted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"nominatedGovernor","type":"address"}],"name":"LogNominatedGovernor","type":"event"},{"anonymous":false,"inputs":[],"name":"LogNominationCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"removedGovernor","type":"address"}],"name":"LogRemovedGovernor","type":"event"},{"anonymous":false,"inputs":[],"name":"LogUnFrozen","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"ethKey","type":"address"},{"indexed":false,"internalType":"uint256","name":"starkKey","type":"uint256"},{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"LogUserRegistered","type":"event"},{"inputs":[],"name":"DEPOSIT_CANCEL_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FREEZE_GRACE_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAIN_GOVERNANCE_INFO_TAG","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_FORCED_ACTIONS_REQS_PER_BLOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_VERIFIER_COUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNFREEZE_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERIFIER_REMOVAL_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultVaultWithdrawalLock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"ownerKey","type":"uint256"},{"internalType":"uint256","name":"vaultId","type":"uint256"}],"name":"freezeRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"ownerKey","type":"uint256"},{"internalType":"uint256","name":"vaultId","type":"uint256"}],"name":"fullWithdrawalRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getActionCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"actionIndex","type":"uint256"}],"name":"getActionHashByIndex","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"ownerKey","type":"uint256"}],"name":"getEthKey","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"ownerKey","type":"uint256"},{"internalType":"uint256","name":"vaultId","type":"uint256"}],"name":"getFullWithdrawalRequest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGlobalConfigCode","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastBatchId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOrderRoot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOrderTreeHeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRollupTreeHeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRollupVaultRoot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSequenceNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getValidiumTreeHeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getValidiumVaultRoot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"identify","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initializerSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isFrozen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mainAcceptGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mainCancelNomination","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"testGovernor","type":"address"}],"name":"mainIsGovernor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newGovernor","type":"address"}],"name":"mainNominateNewGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"governorForRemoval","type":"address"}],"name":"mainRemoveGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"orderRegistryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"ethKey","type":"address"},{"internalType":"uint256","name":"starkKey","type":"uint256"},{"internalType":"bytes","name":"starkSignature","type":"bytes"}],"name":"registerEthAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"starkKey","type":"uint256"},{"internalType":"bytes","name":"starkSignature","type":"bytes"}],"name":"registerSender","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unFreeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"validatedSelectors","outputs":[{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"stateMutability":"pure","type":"function"}]

608060405234801561001057600080fd5b5061259a806100206000396000f3fe608060405234801561001057600080fd5b50600436106101f65760003560e01c80637e9da4c511610120578063a45d7841116100b8578063c23b60ef1161007c578063c23b60ef146105b2578063e30a5cff1461062f578063e6de628214610637578063e9aa2d6b1461063f578063eeb7286614610647576101f6565b8063a45d7841146104f4578063a93310c4146104fc578063b76631121461051f578063bb7c3d3214610527578063bea841871461052f576101f6565b80637e9da4c5146103e857806381b47796146103f057806386aeb445146103f85780638c4bce1c1461046d5780638ed314391461049357806393c1e4661461049b578063993f3639146104be5780639c6a2837146104c6578063a1cc921e146104ce576101f6565b806342af35fd1161019357806342af35fd14610307578063439fab911461030f57806345f5cd971461037d578063515535e8146103a35780635e586cd1146103ab5780635eecd218146103c857806372eb3688146103d057806377e84e0d146103d85780637cf12b90146103e0576101f6565b8062717542146101fb5780630dded952146102155780630ebdac031461021d5780631dbd1da71461027557806328700a15146102ae578063296e2f37146102b857806333eeb147146102db5780633a8cc4fc146102f75780633cc660ad146102ff575b600080fd5b61020361064f565b60408051918252519081900360200190f35b610203610656565b61022561065c565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610261578181015183820152602001610249565b505050509050019250505060405180910390f35b6102926004803603602081101561028b57600080fd5b5035610778565b604080516001600160a01b039092168252519081900360200190f35b6102b66107bf565b005b610203600480360360408110156102ce57600080fd5b50803590602001356107c9565b6102e36107f0565b604080519115158252519081900360200190f35b610203610800565b610203610806565b61020361080b565b6102b66004803603602081101561032557600080fd5b810190602081018135600160201b81111561033f57600080fd5b82018360208201111561035157600080fd5b803590602001918460018302840111600160201b8311171561037257600080fd5b509092509050610811565b6102e36004803603602081101561039357600080fd5b50356001600160a01b0316610850565b610203610861565b610203600480360360208110156103c157600080fd5b5035610867565b6102036108d7565b6102b66108dd565b6102036108e5565b6102b66108ec565b610203610a2b565b610203610a31565b6102b66004803603604081101561040e57600080fd5b81359190810190604081016020820135600160201b81111561042f57600080fd5b82018360208201111561044157600080fd5b803590602001918460018302840111600160201b8311171561046257600080fd5b509092509050610a37565b6102b66004803603602081101561048357600080fd5b50356001600160a01b0316610a48565b610203610a54565b6102b6600480360360408110156104b157600080fd5b5080359060200135610a5a565b610203610b17565b610292610b1f565b6102b6600480360360208110156104e457600080fd5b50356001600160a01b0316610b36565b610203610b3f565b6102b66004803603604081101561051257600080fd5b5080359060200135610b4d565b610203610ca4565b610203610cab565b6102b66004803603606081101561054557600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b81111561057457600080fd5b82018360208201111561058657600080fd5b803590602001918460018302840111600160201b831117156105a757600080fd5b509092509050610cb1565b6105ba610ffa565b6040805160208082528351818301528351919283929083019185019080838360005b838110156105f45781810151838201526020016105dc565b50505050905090810190601f1680156106215780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610203611016565b61020361101b565b610203611020565b6105ba611026565b62093a8081565b600f5490565b604080516003808252608082019092526060919060009082602082018580368337505081519194505060018201916349e0f23360e11b91859190811061069e57fe5b6001600160e01b03199092166020928302919091019091015282516001820191632a4cc43160e21b9185919081106106d257fe5b6001600160e01b0319909216602092830291909101909101528251600182019163bea8418760e01b91859190811061070657fe5b6001600160e01b031990921660209283029190910190910152808214610773576040805162461bcd60e51b815260206004820181905260248201527f494e434f52524543545f53454c4543544f52535f41525241595f4c454e475448604482015290519081900360640190fd5b505090565b6000818152601860205260408120546001600160a01b0316801561079d5790506107ba565b6001600160a01b03831683146107b45760006107b6565b825b9150505b919050565b6107c761105d565b565b6000602260006107d98585611124565b815260200190815260200160002054905092915050565b600454600160a01b900460ff1690565b600d5490565b600090565b600c5490565b6040805162461bcd60e51b815260206004820152600f60248201526e1393d517d253541311535153951151608a1b604482015290519081900360640190fd5b600061085b82611185565b92915050565b601d5490565b60245460009082106108b8576040805162461bcd60e51b815260206004820152601560248201527408286a8929e9cbe929c888ab0bea89e9ebe90928e9605b1b604482015290519081900360640190fd5b602482815481106108c557fe5b90600052602060002001549050919050565b60245490565b6107c76111b4565b6202a30081565b6108f46107f0565b610938576040805162461bcd60e51b815260206004820152601060248201526f29aa20aa22afa727aa2fa32927ad22a760811b604482015290519081900360640190fd5b61094133611185565b610984576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b6005544210156109d6576040805162461bcd60e51b8152602060048201526018602482015277155391949151569157d393d517d0531313d5d15117d6515560421b604482015290519081900360640190fd5b6004805460ff60a01b19169055600d805460019081019091556025805482019055600f805490910190556040517f07017fe9180629cfffba412f65a9affcf9a121de02294179f5c058f881dcc9f890600090a1565b60105490565b60265490565b610a4333848484610cb1565b505050565b610a518161124b565b50565b60255490565b610a626107f0565b15610aa6576040805162461bcd60e51b815260206004820152600f60248201526e29aa20aa22afa4a9afa32927ad22a760891b604482015290519081900360640190fd5b610aaf81611348565b610af8576040805162461bcd60e51b815260206004820152601560248201527413d55517d3d197d4905391d157d59055531517d251605a1b604482015290519081900360640190fd5b6000610b0483836107c9565b9050610b0f81611362565b610a4361145b565b6301e1338081565b68010000000000000004546001600160a01b031681565b610a51816114ef565b680100000000000000035481565b610b556107f0565b15610b99576040805162461bcd60e51b815260206004820152600f60248201526e29aa20aa22afa4a9afa32927ad22a760891b604482015290519081900360640190fd5b81610ba38161163c565b6001600160a01b0316336001600160a01b031614610c08576040805162461bcd60e51b815260206004820152601a60248201527f4d49534d41544348494e475f535441524b5f4554485f4b455953000000000000604482015290519081900360640190fd5b610c1182611348565b610c5a576040805162461bcd60e51b815260206004820152601560248201527413d55517d3d197d4905391d157d59055531517d251605a1b604482015290519081900360640190fd5b610c648383611698565b604080518481526020810184905281517f08eb46dbb87dcfe92d4846e5766802051525fba08a9b48318f5e0fe41186d298929181900390910190a1505050565b6224ea0081565b600e5490565b82610cf7576040805162461bcd60e51b8152602060048201526011602482015270494e56414c49445f535441524b5f4b455960781b604482015290519081900360640190fd5b6001601160c01b01600160fb1b018310610d4c576040805162461bcd60e51b8152602060048201526011602482015270494e56414c49445f535441524b5f4b455960781b604482015290519081900360640190fd5b6001600160a01b038416610d9d576040805162461bcd60e51b8152602060048201526013602482015272494e56414c49445f4554485f4144445245535360681b604482015290519081900360640190fd5b6000838152601860205260409020546001600160a01b031615610dff576040805162461bcd60e51b8152602060048201526015602482015274535441524b5f4b45595f554e415641494c41424c4560581b604482015290519081900360640190fd5b610e08836116ac565b610e4d576040805162461bcd60e51b8152602060048201526011602482015270494e56414c49445f535441524b5f4b455960781b604482015290519081900360640190fd5b60608114610ea2576040805162461bcd60e51b815260206004820152601e60248201527f494e56414c49445f535441524b5f5349474e41545552455f4c454e4754480000604482015290519081900360640190fd5b606082828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052508451949550938493508392506020860191506060811015610ef657600080fd5b5080516020808301516040938401518451702ab9b2b92932b3b4b9ba3930ba34b7b71d60791b8185015260608e901b6bffffffffffffffffffffffff1916603182015260458082018e90528651808303909101815260659091019095528451949092019390932091955091935090915060008051602061251f8339815191529006610f848185858b8661171b565b60008881526018602090815260409182902080546001600160a01b038d166001600160a01b0319909116811790915582519081529081018a9052338183015290517fcab1cf17c190e4e2195a7b8f7b362023246fa774390432b4704ab6b29d56b07b9181900360600190a1505050505050505050565b60405180606001604052806026815260200161253f6026913981565b600a81565b604081565b60275490565b60408051808201909152601e81527f537461726b576172655f466f72636564416374696f6e735f323032325f330000602082015290565b6000611067611a8c565b60018101549091506001600160a01b031633146110c5576040805162461bcd60e51b815260206004820152601760248201527627a7262cafa1a0a72224a220aa22afa3a7ab22a92727a960491b604482015290519081900360640190fd5b60018101546110dc906001600160a01b0316611b09565b6001810180546001600160a01b03191690556040805133815290517fcfb473e6c03f9a29ddaf990e736fa3de5188a0bd85d684f5b6e164ebfbfff5d29181900360200190a150565b600061117e6040518060400160405280600f81526020016e1195531317d5d2551211149055d053608a1b81525084846040516020018083815260200182815260200192505050604051602081830303815290604052611b89565b9392505050565b600080611190611a8c565b6001600160a01b039390931660009081526020939093525050604090205460ff1690565b6111bd33611185565b611200576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b600061120a611a8c565b6001810180546001600160a01b03191690556040519091507f7a8dc7dd7fffb43c4807438fa62729225156941e641fd877938f4edade3429f590600090a150565b61125433611185565b611297576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b60006112a1611a8c565b90506112ac82611185565b156112f1576040805162461bcd60e51b815260206004820152601060248201526f20a62922a0a22cafa3a7ab22a92727a960811b604482015290519081900360640190fd5b6001810180546001600160a01b0384166001600160a01b0319909116811790915560408051918252517f6166272c8d3f5f579082f2827532732f97195007983bb5b83ac12c56700b01a69181900360200190a15050565b600061135382611c4b565b8061085b575061085b82611c60565b806113b0576040805162461bcd60e51b81526020600482015260196024820152781193d490d15117d050d51253d397d553949154555154d51151603a1b604482015290519081900360640190fd5b62093a80818101908110156113c157fe5b8042101561140e576040805162461bcd60e51b8152602060048201526015602482015274464f524345445f414354494f4e5f50454e44494e4760581b604482015290519081900360640190fd5b6005548111611457576040805162461bcd60e51b815260206004820152601060248201526f149151949151569157d055151153541560821b604482015290519081900360640190fd5b5050565b6114636107f0565b156114a7576040805162461bcd60e51b815260206004820152600f60248201526e29aa20aa22afa4a9afa32927ad22a760891b604482015290519081900360640190fd5b426301e13380016005556004805460ff60a01b1916600160a01b1790556040517ff5b8e6419478ab140eb98026ab5bd607038cb0ac4d4dad5b1fc0848dfd203d1f90600090a1565b6114f833611185565b61153b576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b336001600160a01b0382161415611590576040805162461bcd60e51b8152602060048201526014602482015273474f5645524e4f525f53454c465f52454d4f564560601b604482015290519081900360640190fd5b600061159a611a8c565b90506115a582611185565b6115e5576040805162461bcd60e51b815260206004820152600c60248201526b2727aa2fa3a7ab22a92727a960a11b604482015290519081900360640190fd5b6001600160a01b03821660008181526020838152604091829020805460ff19169055815192835290517fd75f94825e770b8b512be8e74759e252ad00e102e38f50cce2f7c6f868a295999281900390910190a15050565b600061164782610778565b90506001600160a01b0381166107ba576040805162461bcd60e51b81526020600482015260116024820152701554d15497d553949151d254d511549151607a1b604482015290519081900360640190fd5b6114576116a58383611124565b6001611c8e565b6000806001601160c01b01600160fb1b01836001601160c01b01600160fb1b018586090990506107b66001601160c01b01600160fb1b017f06f21413efbe40de150e596d72f7a8c5609ad26c15c915c1f4cdfcb99cee9e896001601160c01b01600160fb1b0186850808611d6d565b8460008051602061251f833981519152810614611776576040805162461bcd60e51b81526020600482015260146024820152736d736748617368206f7574206f662072616e676560601b604482015290519081900360640190fd5b82600111158015611794575060008051602061251f83398151915283105b6117d6576040805162461bcd60e51b815260206004820152600e60248201526d73206f7574206f662072616e676560901b604482015290519081900360640190fd5b60006117f08460008051602061251f833981519152611d8d565b9050846001111580156118065750600160fb1b85105b611848576040805162461bcd60e51b815260206004820152600e60248201526d72206f7574206f662072616e676560901b604482015290519081900360640190fd5b8060011115801561185c5750600160fb1b81105b61189e576040805162461bcd60e51b815260206004820152600e60248201526d77206f7574206f662072616e676560901b604482015290519081900360640190fd5b60006001601160c01b01600160fb1b01846001601160c01b01600160fb1b0186870909905060006001601160c01b01600160fb1b0184850990506001601160c01b01600160fb1b017f06f21413efbe40de150e596d72f7a8c5609ad26c15c915c1f4cdfcb99cee9e896001601160c01b01600160fb1b01878508088114611960576040805162461bcd60e51b8152602060048201526011602482015270494e56414c49445f535441524b5f4b455960781b604482015290519081900360640190fd5b50600090508080806119c28a7f01ef15c18599971b7beced415a40f0c7deacfd9b0d1819e03d723d8bc943cfca7e5668060aa49730b7be4801df46ec62de53ecd11abe43a32873000c36e8dc1f60016001601160c01b01600160fb1b01611e39565b90925090506000806119e58b8a8a60016001601160c01b01600160fb1b01611e39565b9092509050611a068484848460016001601160c01b01600160fb1b01611e73565b909650945060009350611a3092508691508590508460016001601160c01b01600160fb1b01611e39565b509050878114611a81576040805162461bcd60e51b8152602060048201526017602482015276494e56414c49445f535441524b5f5349474e415455524560481b604482015290519081900360640190fd5b505050505050505050565b60008060405180606001604052806026815260200161253f602691396040518082805190602001908083835b60208310611ad75780518252601f199092019160209182019101611ab8565b51815160209384036101000a600019018019909216911617905292019485525060405193849003019092209392505050565b611b1281611185565b15611b57576040805162461bcd60e51b815260206004820152601060248201526f20a62922a0a22cafa3a7ab22a92727a960811b604482015290519081900360640190fd5b6000611b61611a8c565b6001600160a01b0390921660009081526020929092525060409020805460ff19166001179055565b600082826040516020018083805190602001908083835b60208310611bbf5780518252601f199092019160209182019101611ba0565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b60208310611c075780518252601f199092019160209182019101611be8565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405280519060200120905092915050565b6000611c55610cab565b60020a909110919050565b60006001603f1b81611c70610a31565b60020a82019050838211158015611c8657508084105b949350505050565b8015611caf5760005b615289811015611ca957600101611c97565b50611d2a565b43600090815260216020526040902054600a11611d13576040805162461bcd60e51b815260206004820152601e60248201527f4d41585f52455155455354535f5045525f424c4f434b5f524541434845440000604482015290519081900360640190fd5b436000908152602160205260409020805460010190555b5060008181526022602052604081204290556024805460018101825591527f7cd332d19b93bcabe3cce7ca0c18a052f57e5fd03b4758a09f30f5ddc4b22ec40155565b6000611d848267080000000000001160bf1b611ef3565b60011492915050565b60008215801590611d9e5750818314155b8015611da957508115155b611deb576040805162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b210373ab6b132b960911b604482015290519081900360640190fd5b6000600183825b8615611e2e57868281611e0157fe5b049050828680611e0d57fe5b8780611e1557fe5b8584098803860882890290930397909450919250611df2565b509195945050505050565b6000806000806000611e508a8a8a60018b8b61209f565b925092509250611e6283838389612116565b945094505050509550959350505050565b6000806000806000888b1415611ebb578580611e8b57fe5b888b08611ea15760008094509450505050611ee8565b611eaf8b8b60018a8a61216d565b91945092509050611ed4565b611ecc8b8b60018c8c60018c612283565b919450925090505b611ee083838389612116565b945094505050505b965096945050505050565b600080606060056001600160a01b0316602080602088886001601160c01b01600160fb1b016040516020018087815260200186815260200185815260200184815260200183815260200182815260200196505050505050506040516020818303038152906040526040518082805190602001908083835b60208310611f895780518252601f199092019160209182019101611f6a565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114611fe9576040519150601f19603f3d011682016040523d82523d6000602084013e611fee565b606091505b509150915081819061207e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561204357818101518382015260200161202b565b50505050905090810190601f1680156120705780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5080806020019051602081101561209457600080fd5b505195945050505050565b60008080886120b557508691508590508461210a565b8860008060015b83156121015760018416156120e2576120da8383838f8f8f8e612283565b919450925090505b6002840493506120f58c8c8c8c8c61216d565b919d509b5099506120bc565b91955093509150505b96509650969350505050565b60008060006121258585611d8d565b90506000848061213157fe5b82830990506000858061214057fe5b828a0990506000868061214f57fe5b878061215757fe5b8486098a09919a91995090975050505050505050565b6000808085612183575086915085905084612278565b6000848061218d57fe5b898a0990506000858061219c57fe5b898a099050600086806121ab57fe5b898a099050600087806121ba57fe5b88806121c257fe5b848e096004099050600088806121d457fe5b89806121dc57fe5b8a806121e457fe5b8586098c098a806121f157fe5b87600309089050888061220057fe5b898061220857fe5b8384088a038a8061221557fe5b838409089450888061222357fe5b898061222b57fe5b8a8061223357fe5b8687096008098a038a8061224357fe5b8b8061224b57fe5b888d0386088409089350888061225d57fe5b898061226557fe5b8c8e096002099497509295509293505050505b955095509592505050565b6000808089158015612293575088155b156122a55750859150849050836124f3565b861580156122b1575085155b156122c35750889150879050866124f3565b6122cb612500565b84806122d357fe5b898a09815284806122e057fe5b81518a09602082015284806122f157fe5b8687096040820152848061230157fe5b604082015187096060820152604080516080810190915280868061232157fe5b60408401518e098152602001868061233557fe5b60608401518d098152602001868061234957fe5b83518b098152602001868061235a57fe5b60208401518a0990526040810151815191925014158061238257506060810151602082015114155b6123d3576040805162461bcd60e51b815260206004820152601e60248201527f557365206a6163446f75626c652066756e6374696f6e20696e73746561640000604482015290519081900360640190fd5b6123db612500565b85806123e357fe5b825160408401519088039008815285806123f957fe5b6020830151606084015190880390086020820152858061241557fe5b815180096040820152858061242657fe5b815160408301510960608201526000868061243d57fe5b60608301518803888061244c57fe5b60208501518009089050868061245e57fe5b878061246657fe5b888061246e57fe5b60408501518651096002098803820890506000878061248957fe5b888061249157fe5b838a038a8061249c57fe5b604087015188510908602085015109905087806124b557fe5b88806124bd57fe5b6060850151602087015109890382089050600088806124d857fe5b89806124e057fe5b8b8f098551099297509095509093505050505b9750975097945050505050565b6040518060800160405280600490602082028036833750919291505056fe0800000000000010ffffffffffffffffb781126dcae7b2321e66a241adc64d2f537461726b45782e4d61696e2e323031392e476f7665726e6f7273496e666f726d6174696f6ea26469706673582212202a6988e2bd31c7b7a88d91f948bb5865e867cf9778e3a2decf940e6c404e1f7964736f6c634300060c0033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101f65760003560e01c80637e9da4c511610120578063a45d7841116100b8578063c23b60ef1161007c578063c23b60ef146105b2578063e30a5cff1461062f578063e6de628214610637578063e9aa2d6b1461063f578063eeb7286614610647576101f6565b8063a45d7841146104f4578063a93310c4146104fc578063b76631121461051f578063bb7c3d3214610527578063bea841871461052f576101f6565b80637e9da4c5146103e857806381b47796146103f057806386aeb445146103f85780638c4bce1c1461046d5780638ed314391461049357806393c1e4661461049b578063993f3639146104be5780639c6a2837146104c6578063a1cc921e146104ce576101f6565b806342af35fd1161019357806342af35fd14610307578063439fab911461030f57806345f5cd971461037d578063515535e8146103a35780635e586cd1146103ab5780635eecd218146103c857806372eb3688146103d057806377e84e0d146103d85780637cf12b90146103e0576101f6565b8062717542146101fb5780630dded952146102155780630ebdac031461021d5780631dbd1da71461027557806328700a15146102ae578063296e2f37146102b857806333eeb147146102db5780633a8cc4fc146102f75780633cc660ad146102ff575b600080fd5b61020361064f565b60408051918252519081900360200190f35b610203610656565b61022561065c565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610261578181015183820152602001610249565b505050509050019250505060405180910390f35b6102926004803603602081101561028b57600080fd5b5035610778565b604080516001600160a01b039092168252519081900360200190f35b6102b66107bf565b005b610203600480360360408110156102ce57600080fd5b50803590602001356107c9565b6102e36107f0565b604080519115158252519081900360200190f35b610203610800565b610203610806565b61020361080b565b6102b66004803603602081101561032557600080fd5b810190602081018135600160201b81111561033f57600080fd5b82018360208201111561035157600080fd5b803590602001918460018302840111600160201b8311171561037257600080fd5b509092509050610811565b6102e36004803603602081101561039357600080fd5b50356001600160a01b0316610850565b610203610861565b610203600480360360208110156103c157600080fd5b5035610867565b6102036108d7565b6102b66108dd565b6102036108e5565b6102b66108ec565b610203610a2b565b610203610a31565b6102b66004803603604081101561040e57600080fd5b81359190810190604081016020820135600160201b81111561042f57600080fd5b82018360208201111561044157600080fd5b803590602001918460018302840111600160201b8311171561046257600080fd5b509092509050610a37565b6102b66004803603602081101561048357600080fd5b50356001600160a01b0316610a48565b610203610a54565b6102b6600480360360408110156104b157600080fd5b5080359060200135610a5a565b610203610b17565b610292610b1f565b6102b6600480360360208110156104e457600080fd5b50356001600160a01b0316610b36565b610203610b3f565b6102b66004803603604081101561051257600080fd5b5080359060200135610b4d565b610203610ca4565b610203610cab565b6102b66004803603606081101561054557600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b81111561057457600080fd5b82018360208201111561058657600080fd5b803590602001918460018302840111600160201b831117156105a757600080fd5b509092509050610cb1565b6105ba610ffa565b6040805160208082528351818301528351919283929083019185019080838360005b838110156105f45781810151838201526020016105dc565b50505050905090810190601f1680156106215780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610203611016565b61020361101b565b610203611020565b6105ba611026565b62093a8081565b600f5490565b604080516003808252608082019092526060919060009082602082018580368337505081519194505060018201916349e0f23360e11b91859190811061069e57fe5b6001600160e01b03199092166020928302919091019091015282516001820191632a4cc43160e21b9185919081106106d257fe5b6001600160e01b0319909216602092830291909101909101528251600182019163bea8418760e01b91859190811061070657fe5b6001600160e01b031990921660209283029190910190910152808214610773576040805162461bcd60e51b815260206004820181905260248201527f494e434f52524543545f53454c4543544f52535f41525241595f4c454e475448604482015290519081900360640190fd5b505090565b6000818152601860205260408120546001600160a01b0316801561079d5790506107ba565b6001600160a01b03831683146107b45760006107b6565b825b9150505b919050565b6107c761105d565b565b6000602260006107d98585611124565b815260200190815260200160002054905092915050565b600454600160a01b900460ff1690565b600d5490565b600090565b600c5490565b6040805162461bcd60e51b815260206004820152600f60248201526e1393d517d253541311535153951151608a1b604482015290519081900360640190fd5b600061085b82611185565b92915050565b601d5490565b60245460009082106108b8576040805162461bcd60e51b815260206004820152601560248201527408286a8929e9cbe929c888ab0bea89e9ebe90928e9605b1b604482015290519081900360640190fd5b602482815481106108c557fe5b90600052602060002001549050919050565b60245490565b6107c76111b4565b6202a30081565b6108f46107f0565b610938576040805162461bcd60e51b815260206004820152601060248201526f29aa20aa22afa727aa2fa32927ad22a760811b604482015290519081900360640190fd5b61094133611185565b610984576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b6005544210156109d6576040805162461bcd60e51b8152602060048201526018602482015277155391949151569157d393d517d0531313d5d15117d6515560421b604482015290519081900360640190fd5b6004805460ff60a01b19169055600d805460019081019091556025805482019055600f805490910190556040517f07017fe9180629cfffba412f65a9affcf9a121de02294179f5c058f881dcc9f890600090a1565b60105490565b60265490565b610a4333848484610cb1565b505050565b610a518161124b565b50565b60255490565b610a626107f0565b15610aa6576040805162461bcd60e51b815260206004820152600f60248201526e29aa20aa22afa4a9afa32927ad22a760891b604482015290519081900360640190fd5b610aaf81611348565b610af8576040805162461bcd60e51b815260206004820152601560248201527413d55517d3d197d4905391d157d59055531517d251605a1b604482015290519081900360640190fd5b6000610b0483836107c9565b9050610b0f81611362565b610a4361145b565b6301e1338081565b68010000000000000004546001600160a01b031681565b610a51816114ef565b680100000000000000035481565b610b556107f0565b15610b99576040805162461bcd60e51b815260206004820152600f60248201526e29aa20aa22afa4a9afa32927ad22a760891b604482015290519081900360640190fd5b81610ba38161163c565b6001600160a01b0316336001600160a01b031614610c08576040805162461bcd60e51b815260206004820152601a60248201527f4d49534d41544348494e475f535441524b5f4554485f4b455953000000000000604482015290519081900360640190fd5b610c1182611348565b610c5a576040805162461bcd60e51b815260206004820152601560248201527413d55517d3d197d4905391d157d59055531517d251605a1b604482015290519081900360640190fd5b610c648383611698565b604080518481526020810184905281517f08eb46dbb87dcfe92d4846e5766802051525fba08a9b48318f5e0fe41186d298929181900390910190a1505050565b6224ea0081565b600e5490565b82610cf7576040805162461bcd60e51b8152602060048201526011602482015270494e56414c49445f535441524b5f4b455960781b604482015290519081900360640190fd5b6001601160c01b01600160fb1b018310610d4c576040805162461bcd60e51b8152602060048201526011602482015270494e56414c49445f535441524b5f4b455960781b604482015290519081900360640190fd5b6001600160a01b038416610d9d576040805162461bcd60e51b8152602060048201526013602482015272494e56414c49445f4554485f4144445245535360681b604482015290519081900360640190fd5b6000838152601860205260409020546001600160a01b031615610dff576040805162461bcd60e51b8152602060048201526015602482015274535441524b5f4b45595f554e415641494c41424c4560581b604482015290519081900360640190fd5b610e08836116ac565b610e4d576040805162461bcd60e51b8152602060048201526011602482015270494e56414c49445f535441524b5f4b455960781b604482015290519081900360640190fd5b60608114610ea2576040805162461bcd60e51b815260206004820152601e60248201527f494e56414c49445f535441524b5f5349474e41545552455f4c454e4754480000604482015290519081900360640190fd5b606082828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052508451949550938493508392506020860191506060811015610ef657600080fd5b5080516020808301516040938401518451702ab9b2b92932b3b4b9ba3930ba34b7b71d60791b8185015260608e901b6bffffffffffffffffffffffff1916603182015260458082018e90528651808303909101815260659091019095528451949092019390932091955091935090915060008051602061251f8339815191529006610f848185858b8661171b565b60008881526018602090815260409182902080546001600160a01b038d166001600160a01b0319909116811790915582519081529081018a9052338183015290517fcab1cf17c190e4e2195a7b8f7b362023246fa774390432b4704ab6b29d56b07b9181900360600190a1505050505050505050565b60405180606001604052806026815260200161253f6026913981565b600a81565b604081565b60275490565b60408051808201909152601e81527f537461726b576172655f466f72636564416374696f6e735f323032325f330000602082015290565b6000611067611a8c565b60018101549091506001600160a01b031633146110c5576040805162461bcd60e51b815260206004820152601760248201527627a7262cafa1a0a72224a220aa22afa3a7ab22a92727a960491b604482015290519081900360640190fd5b60018101546110dc906001600160a01b0316611b09565b6001810180546001600160a01b03191690556040805133815290517fcfb473e6c03f9a29ddaf990e736fa3de5188a0bd85d684f5b6e164ebfbfff5d29181900360200190a150565b600061117e6040518060400160405280600f81526020016e1195531317d5d2551211149055d053608a1b81525084846040516020018083815260200182815260200192505050604051602081830303815290604052611b89565b9392505050565b600080611190611a8c565b6001600160a01b039390931660009081526020939093525050604090205460ff1690565b6111bd33611185565b611200576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b600061120a611a8c565b6001810180546001600160a01b03191690556040519091507f7a8dc7dd7fffb43c4807438fa62729225156941e641fd877938f4edade3429f590600090a150565b61125433611185565b611297576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b60006112a1611a8c565b90506112ac82611185565b156112f1576040805162461bcd60e51b815260206004820152601060248201526f20a62922a0a22cafa3a7ab22a92727a960811b604482015290519081900360640190fd5b6001810180546001600160a01b0384166001600160a01b0319909116811790915560408051918252517f6166272c8d3f5f579082f2827532732f97195007983bb5b83ac12c56700b01a69181900360200190a15050565b600061135382611c4b565b8061085b575061085b82611c60565b806113b0576040805162461bcd60e51b81526020600482015260196024820152781193d490d15117d050d51253d397d553949154555154d51151603a1b604482015290519081900360640190fd5b62093a80818101908110156113c157fe5b8042101561140e576040805162461bcd60e51b8152602060048201526015602482015274464f524345445f414354494f4e5f50454e44494e4760581b604482015290519081900360640190fd5b6005548111611457576040805162461bcd60e51b815260206004820152601060248201526f149151949151569157d055151153541560821b604482015290519081900360640190fd5b5050565b6114636107f0565b156114a7576040805162461bcd60e51b815260206004820152600f60248201526e29aa20aa22afa4a9afa32927ad22a760891b604482015290519081900360640190fd5b426301e13380016005556004805460ff60a01b1916600160a01b1790556040517ff5b8e6419478ab140eb98026ab5bd607038cb0ac4d4dad5b1fc0848dfd203d1f90600090a1565b6114f833611185565b61153b576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b336001600160a01b0382161415611590576040805162461bcd60e51b8152602060048201526014602482015273474f5645524e4f525f53454c465f52454d4f564560601b604482015290519081900360640190fd5b600061159a611a8c565b90506115a582611185565b6115e5576040805162461bcd60e51b815260206004820152600c60248201526b2727aa2fa3a7ab22a92727a960a11b604482015290519081900360640190fd5b6001600160a01b03821660008181526020838152604091829020805460ff19169055815192835290517fd75f94825e770b8b512be8e74759e252ad00e102e38f50cce2f7c6f868a295999281900390910190a15050565b600061164782610778565b90506001600160a01b0381166107ba576040805162461bcd60e51b81526020600482015260116024820152701554d15497d553949151d254d511549151607a1b604482015290519081900360640190fd5b6114576116a58383611124565b6001611c8e565b6000806001601160c01b01600160fb1b01836001601160c01b01600160fb1b018586090990506107b66001601160c01b01600160fb1b017f06f21413efbe40de150e596d72f7a8c5609ad26c15c915c1f4cdfcb99cee9e896001601160c01b01600160fb1b0186850808611d6d565b8460008051602061251f833981519152810614611776576040805162461bcd60e51b81526020600482015260146024820152736d736748617368206f7574206f662072616e676560601b604482015290519081900360640190fd5b82600111158015611794575060008051602061251f83398151915283105b6117d6576040805162461bcd60e51b815260206004820152600e60248201526d73206f7574206f662072616e676560901b604482015290519081900360640190fd5b60006117f08460008051602061251f833981519152611d8d565b9050846001111580156118065750600160fb1b85105b611848576040805162461bcd60e51b815260206004820152600e60248201526d72206f7574206f662072616e676560901b604482015290519081900360640190fd5b8060011115801561185c5750600160fb1b81105b61189e576040805162461bcd60e51b815260206004820152600e60248201526d77206f7574206f662072616e676560901b604482015290519081900360640190fd5b60006001601160c01b01600160fb1b01846001601160c01b01600160fb1b0186870909905060006001601160c01b01600160fb1b0184850990506001601160c01b01600160fb1b017f06f21413efbe40de150e596d72f7a8c5609ad26c15c915c1f4cdfcb99cee9e896001601160c01b01600160fb1b01878508088114611960576040805162461bcd60e51b8152602060048201526011602482015270494e56414c49445f535441524b5f4b455960781b604482015290519081900360640190fd5b50600090508080806119c28a7f01ef15c18599971b7beced415a40f0c7deacfd9b0d1819e03d723d8bc943cfca7e5668060aa49730b7be4801df46ec62de53ecd11abe43a32873000c36e8dc1f60016001601160c01b01600160fb1b01611e39565b90925090506000806119e58b8a8a60016001601160c01b01600160fb1b01611e39565b9092509050611a068484848460016001601160c01b01600160fb1b01611e73565b909650945060009350611a3092508691508590508460016001601160c01b01600160fb1b01611e39565b509050878114611a81576040805162461bcd60e51b8152602060048201526017602482015276494e56414c49445f535441524b5f5349474e415455524560481b604482015290519081900360640190fd5b505050505050505050565b60008060405180606001604052806026815260200161253f602691396040518082805190602001908083835b60208310611ad75780518252601f199092019160209182019101611ab8565b51815160209384036101000a600019018019909216911617905292019485525060405193849003019092209392505050565b611b1281611185565b15611b57576040805162461bcd60e51b815260206004820152601060248201526f20a62922a0a22cafa3a7ab22a92727a960811b604482015290519081900360640190fd5b6000611b61611a8c565b6001600160a01b0390921660009081526020929092525060409020805460ff19166001179055565b600082826040516020018083805190602001908083835b60208310611bbf5780518252601f199092019160209182019101611ba0565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b60208310611c075780518252601f199092019160209182019101611be8565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405280519060200120905092915050565b6000611c55610cab565b60020a909110919050565b60006001603f1b81611c70610a31565b60020a82019050838211158015611c8657508084105b949350505050565b8015611caf5760005b615289811015611ca957600101611c97565b50611d2a565b43600090815260216020526040902054600a11611d13576040805162461bcd60e51b815260206004820152601e60248201527f4d41585f52455155455354535f5045525f424c4f434b5f524541434845440000604482015290519081900360640190fd5b436000908152602160205260409020805460010190555b5060008181526022602052604081204290556024805460018101825591527f7cd332d19b93bcabe3cce7ca0c18a052f57e5fd03b4758a09f30f5ddc4b22ec40155565b6000611d848267080000000000001160bf1b611ef3565b60011492915050565b60008215801590611d9e5750818314155b8015611da957508115155b611deb576040805162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b210373ab6b132b960911b604482015290519081900360640190fd5b6000600183825b8615611e2e57868281611e0157fe5b049050828680611e0d57fe5b8780611e1557fe5b8584098803860882890290930397909450919250611df2565b509195945050505050565b6000806000806000611e508a8a8a60018b8b61209f565b925092509250611e6283838389612116565b945094505050509550959350505050565b6000806000806000888b1415611ebb578580611e8b57fe5b888b08611ea15760008094509450505050611ee8565b611eaf8b8b60018a8a61216d565b91945092509050611ed4565b611ecc8b8b60018c8c60018c612283565b919450925090505b611ee083838389612116565b945094505050505b965096945050505050565b600080606060056001600160a01b0316602080602088886001601160c01b01600160fb1b016040516020018087815260200186815260200185815260200184815260200183815260200182815260200196505050505050506040516020818303038152906040526040518082805190602001908083835b60208310611f895780518252601f199092019160209182019101611f6a565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114611fe9576040519150601f19603f3d011682016040523d82523d6000602084013e611fee565b606091505b509150915081819061207e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561204357818101518382015260200161202b565b50505050905090810190601f1680156120705780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5080806020019051602081101561209457600080fd5b505195945050505050565b60008080886120b557508691508590508461210a565b8860008060015b83156121015760018416156120e2576120da8383838f8f8f8e612283565b919450925090505b6002840493506120f58c8c8c8c8c61216d565b919d509b5099506120bc565b91955093509150505b96509650969350505050565b60008060006121258585611d8d565b90506000848061213157fe5b82830990506000858061214057fe5b828a0990506000868061214f57fe5b878061215757fe5b8486098a09919a91995090975050505050505050565b6000808085612183575086915085905084612278565b6000848061218d57fe5b898a0990506000858061219c57fe5b898a099050600086806121ab57fe5b898a099050600087806121ba57fe5b88806121c257fe5b848e096004099050600088806121d457fe5b89806121dc57fe5b8a806121e457fe5b8586098c098a806121f157fe5b87600309089050888061220057fe5b898061220857fe5b8384088a038a8061221557fe5b838409089450888061222357fe5b898061222b57fe5b8a8061223357fe5b8687096008098a038a8061224357fe5b8b8061224b57fe5b888d0386088409089350888061225d57fe5b898061226557fe5b8c8e096002099497509295509293505050505b955095509592505050565b6000808089158015612293575088155b156122a55750859150849050836124f3565b861580156122b1575085155b156122c35750889150879050866124f3565b6122cb612500565b84806122d357fe5b898a09815284806122e057fe5b81518a09602082015284806122f157fe5b8687096040820152848061230157fe5b604082015187096060820152604080516080810190915280868061232157fe5b60408401518e098152602001868061233557fe5b60608401518d098152602001868061234957fe5b83518b098152602001868061235a57fe5b60208401518a0990526040810151815191925014158061238257506060810151602082015114155b6123d3576040805162461bcd60e51b815260206004820152601e60248201527f557365206a6163446f75626c652066756e6374696f6e20696e73746561640000604482015290519081900360640190fd5b6123db612500565b85806123e357fe5b825160408401519088039008815285806123f957fe5b6020830151606084015190880390086020820152858061241557fe5b815180096040820152858061242657fe5b815160408301510960608201526000868061243d57fe5b60608301518803888061244c57fe5b60208501518009089050868061245e57fe5b878061246657fe5b888061246e57fe5b60408501518651096002098803820890506000878061248957fe5b888061249157fe5b838a038a8061249c57fe5b604087015188510908602085015109905087806124b557fe5b88806124bd57fe5b6060850151602087015109890382089050600088806124d857fe5b89806124e057fe5b8b8f098551099297509095509093505050505b9750975097945050505050565b6040518060800160405280600490602082028036833750919291505056fe0800000000000010ffffffffffffffffb781126dcae7b2321e66a241adc64d2f537461726b45782e4d61696e2e323031392e476f7665726e6f7273496e666f726d6174696f6ea26469706673582212202a6988e2bd31c7b7a88d91f948bb5865e867cf9778e3a2decf940e6c404e1f7964736f6c634300060c0033

Deployed Bytecode Sourcemap

858:1045:4:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1246:52:11;;;:::i;:::-;;;;;;;;;;;;;;;;1950:89:22;;;:::i;1247:525:4:-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1444:314:10;;;;;;;;;;;;;;;;-1:-1:-1;1444:314:10;;:::i;:::-;;;;-1:-1:-1;;;;;1444:314:10;;;;;;;;;;;;;;3095:77:17;;;:::i;:::-;;1454:370:20;;;;;;;;;;;;;;;;-1:-1:-1;1454:370:20;;;;;;;:::i;935:91:5:-;;;:::i;:::-;;;;;;;;;;;;;;;;;;1482:112:22;;;:::i;1148:93:4:-;;;:::i;2152:99:22:-;;;:::i;1021:121:4:-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;1021:121:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;1021:121:4;;;;;;;;;;-1:-1:-1;1021:121:4;;-1:-1:-1;1021:121:4;-1:-1:-1;1021:121:4;:::i;2723:124:17:-;;;;;;;;;;;;;;;;-1:-1:-1;2723:124:17;-1:-1:-1;;;;;2723:124:17;;:::i;2257:93:22:-;;;:::i;2133:213:0:-;;;;;;;;;;;;;;;;-1:-1:-1;2133:213:0;;:::i;2024:103::-;;;:::i;3178:77:17:-;;;:::i;1059:53:11:-;;;:::i;1845:404:5:-;;;:::i;2045:101:22:-;;;:::i;1834:110::-;;;:::i;2917:155:24:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;2917:155:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;2917:155:24;;;;;;;;;;-1:-1:-1;2917:155:24;;-1:-1:-1;2917:155:24;-1:-1:-1;2917:155:24;:::i;2853:113:17:-;;;;;;;;;;;;;;;;-1:-1:-1;2853:113:17;-1:-1:-1;;;;;2853:113:17;;:::i;1720:108:22:-;;;:::i;3834:356:6:-;;;;;;;;;;;;;;;;-1:-1:-1;3834:356:6;;;;;;;:::i;1473:49:11:-;;;:::i;1864:35:21:-;;;:::i;2972:117:17:-;;;;;;;;;;;;;;;;-1:-1:-1;2972:117:17;-1:-1:-1;;;;;2972:117:17;;:::i;1696:41:21:-;;;:::i;3402:426:6:-;;;;;;;;;;;;;;;;-1:-1:-1;3402:426:6;;;;;;;:::i;1724:80:11:-;;;:::i;1600:114:22:-;;;:::i;3078:1071:24:-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3078:1071:24;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;3078:1071:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;3078:1071:24;;;;;;;;;;-1:-1:-1;3078:1071:24;;-1:-1:-1;3078:1071:24;-1:-1:-1;3078:1071:24;:::i;2376:90:17:-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2292:62:11;;;:::i;1584:56::-;;;:::i;2356:103:22:-;;;:::i;1778:123:4:-;;;:::i;1246:52:11:-;1292:6;1246:52;:::o;1950:89:22:-;2023:9;;1950:89;:::o;1247:525:4:-;1465:18;;;1413:1;1465:18;;;;;;;;;1357:25;;1413:1;1398:12;;1413:1;1465:18;;;1357:25;;1465:18;;;-1:-1:-1;;1493:19:4;;1453:30;;-1:-1:-1;;1503:8:4;;;;-1:-1:-1;;;1515:38:4;1453:30;;1503:8;1493:19;;;;;;-1:-1:-1;;;;;;1493:60:4;;;:19;;;;;;;;;;;:60;1563:19;;1573:8;;;;-1:-1:-1;;;1585:46:4;1563:9;;1573:8;1563:19;;;;;;-1:-1:-1;;;;;;1563:68:4;;;:19;;;;;;;;;;;:68;1641:19;;1651:8;;;;-1:-1:-1;;;1663:33:4;1641:9;;1651:8;1641:19;;;;;;-1:-1:-1;;;;;;1641:55:4;;;:19;;;;;;;;;;;:55;1714:14;;;1706:59;;;;;-1:-1:-1;;;1706:59:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1247:525;;;:::o;1444:314:10:-;1511:7;1554:17;;;:7;:17;;;;;;-1:-1:-1;;;;;1554:17:10;1586:29;;1582:80;;1638:13;-1:-1:-1;1631:20:10;;1582:80;-1:-1:-1;;;;;1692:8:10;:23;1679:8;:37;:72;;1747:3;1679:72;;;1727:8;1679:72;1672:79;;;1444:314;;;;:::o;3095:77:17:-;3146:19;:17;:19::i;:::-;3095:77::o;1454:370:20:-;1585:7;1754:20;:63;1775:41;1798:8;1808:7;1775:22;:41::i;:::-;1754:63;;;;;;;;;;;;1747:70;;1454:370;;;;:::o;935:91:5:-;1008:11;;-1:-1:-1;;;1008:11:5;;;;;935:91::o;1482:112:22:-;1570:17;;1482:112;:::o;1148:93:4:-;1207:7;1148:93;:::o;2152:99:22:-;2230:14;;2152:99;:::o;1021:121:4:-;1110:25;;;-1:-1:-1;;;1110:25:4;;;;;;;;;;;;-1:-1:-1;;;1110:25:4;;;;;;;;;;;;;;2723:124:17;2792:4;2815:25;2827:12;2815:11;:25::i;:::-;2808:32;2723:124;-1:-1:-1;;2723:124:17:o;2257:93:22:-;2332:11;;2257:93;:::o;2133:213:0:-;2248:14;:21;2207:7;;2234:35;;2226:69;;;;;-1:-1:-1;;;2226:69:0;;;;;;;;;;;;-1:-1:-1;;;2226:69:0;;;;;;;;;;;;;;;2312:14;2327:11;2312:27;;;;;;;;;;;;;;;;2305:34;;2133:213;;;:::o;2024:103::-;2099:14;:21;2024:103;:::o;3178:77:17:-;3229:19;:17;:19::i;1059:53:11:-;1106:6;1059:53;:::o;1845:404:5:-;1213:10:12;:8;:10::i;:::-;1205:39;;;;;-1:-1:-1;;;1205:39:12;;;;;;;;;;;;-1:-1:-1;;;1205:39:12;;;;;;;;;;;;;;;1031:23:13::1;1043:10;1031:11;:23::i;:::-;1023:51;;;::::0;;-1:-1:-1;;;1023:51:13;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;1023:51:13;;;;;;;;;;;;;::::1;;1937:12:5::2;;1918:15;:31;;1910:68;;;::::0;;-1:-1:-1;;;1910:68:5;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;1910:68:5;;;;;;;;;;;;;::::2;;2014:11;:19:::0;;-1:-1:-1;;;;2014:19:5::2;::::0;;2115:17:::2;:22:::0;;2014:19;2115:22;;::::2;::::0;;;2147:15:::2;:20:::0;;;::::2;::::0;;2177:9:::2;:14:::0;;;;::::2;::::0;;2229:13:::2;::::0;::::2;::::0;2028:5:::2;::::0;2229:13:::2;1845:404::o:0;2045:101:22:-;2124:15;;2045:101;:::o;1834:110::-;1921:16;;1834:110;:::o;2917:155:24:-;3009:56;3028:10;3040:8;3050:14;;3009:18;:56::i;:::-;2917:155;;;:::o;2853:113:17:-;2926:33;2947:11;2926:20;:33::i;:::-;2853:113;:::o;1720:108:22:-;1806:15;;1720:108;:::o;3834:356:6:-;964:10:12;:8;:10::i;:::-;963:11;955:39;;;;;-1:-1:-1;;;955:39:12;;;;;;;;;;;;-1:-1:-1;;;955:39:12;;;;;;;;;;;;;;;3965:23:6::1;3980:7;3965:14;:23::i;:::-;3957:57;;;::::0;;-1:-1:-1;;;3957:57:6;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;3957:57:6;;;;;;;;;;;;;::::1;;4055:19;4077:43;4102:8;4112:7;4077:24;:43::i;:::-;4055:65;;4131:34;4153:11;4131:21;:34::i;:::-;4175:8;:6;:8::i;1473:49:11:-:0;1514:8;1473:49;:::o;1864:35:21:-;;;-1:-1:-1;;;;;1864:35:21;;:::o;2972:117:17:-;3047:35;3063:18;3047:15;:35::i;1696:41:21:-;;;;:::o;3402:426:6:-;964:10:12;:8;:10::i;:::-;963:11;955:39;;;;;-1:-1:-1;;;955:39:12;;;;;;;;;;;;-1:-1:-1;;;955:39:12;;;;;;;;;;;;;;;3524:8:6::1;1224:25:14;1240:8;1224:15;:25::i;:::-;-1:-1:-1::0;;;;;1210:39:14::1;:10;-1:-1:-1::0;;;;;1210:39:14::1;;1202:78;;;::::0;;-1:-1:-1;;;1202:78:14;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;3593:23:6::2;3608:7;3593:14;:23::i;:::-;3585:57;;;::::0;;-1:-1:-1;;;3585:57:6;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;3585:57:6;;;;;;;;;;;;;::::2;;3695:43;3720:8;3730:7;3695:24;:43::i;:::-;3778;::::0;;;;;::::2;::::0;::::2;::::0;;;;;::::2;::::0;;;;;;;;;::::2;1004:1:12::1;3402:426:6::0;;:::o;1724:80:11:-;1773:31;1724:80;:::o;1600:114:22:-;1689:18;;1600:114;:::o;3078:1071:24:-;3269:13;3261:43;;;;;-1:-1:-1;;;3261:43:24;;;;;;;;;;;;-1:-1:-1;;;3261:43:24;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;3322:8:24;:20;3314:50;;;;;-1:-1:-1;;;3314:50:24;;;;;;;;;;;;-1:-1:-1;;;3314:50:24;;;;;;;;;;;;;;;-1:-1:-1;;;;;3382:22:24;;3374:54;;;;;-1:-1:-1;;;3374:54:24;;;;;;;;;;;;-1:-1:-1;;;3374:54:24;;;;;;;;;;;;;;;1851:3:11;3446:17:24;;;:7;:17;;;;;;-1:-1:-1;;;;;3446:17:24;:33;3438:67;;;;;-1:-1:-1;;;3438:67:24;;;;;;;;;;;;-1:-1:-1;;;3438:67:24;;;;;;;;;;;;;;;3523:19;3533:8;3523:9;:19::i;:::-;3515:49;;;;;-1:-1:-1;;;3515:49:24;;;;;;;;;;;;-1:-1:-1;;;3515:49:24;;;;;;;;;;;;;;;3607:6;3582:31;;3574:74;;;;;-1:-1:-1;;;3574:74:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;3659:16;3678:14;;3659:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3746:44:24;;3659:33;;-1:-1:-1;3659:33:24;;;-1:-1:-1;3659:33:24;;-1:-1:-1;3746:44:24;;;;-1:-1:-1;3746:44:24;;;;;;;;;;-1:-1:-1;3746:44:24;;;;;;;;;;;;3850:55;;-1:-1:-1;;;3850:55:24;;;;3746:44;3850:55;;;-1:-1:-1;;3850:55:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3840:66;;;;;;;;;;3746:44;;-1:-1:-1;3746:44:24;;-1:-1:-1;3746:44:24;;-1:-1:-1;;;;;;;;;;;;3819:114:24;;3944:48;3819:114;3746:44;;3850:55;3746:44;3944:12;:48::i;:::-;4028:17;;;;:7;:17;;;;;;;;;:26;;-1:-1:-1;;;;;4028:26:24;;-1:-1:-1;;;;;;4028:26:24;;;;;;;;4095:47;;;;;;;;;;;4131:10;4095:47;;;;;;;;;;;;;;;3078:1071;;;;;;;;;:::o;2376:90:17:-;;;;;;;;;;;;;;;;;;;:::o;2292:62:11:-;2352:2;2292:62;:::o;1584:56::-;1637:2;1584:56;:::o;2356:103:22:-;2436:16;;2356:103;:::o;1778:123:4:-;1855:39;;;;;;;;;;;;;;;;;1778:123;:::o;3782:498:7:-;3911:32;3946:19;:17;:19::i;:::-;3997:21;;;;;;-1:-1:-1;;;;;;3997:21:7;3983:10;:35;3975:71;;;;;-1:-1:-1;;;3975:71:7;;;;;;;;;;;;-1:-1:-1;;;3975:71:7;;;;;;;;;;;;;;;4094:21;;;;4082:34;;-1:-1:-1;;;;;4094:21:7;4082:11;:34::i;:::-;4126:21;;;:36;;-1:-1:-1;;;;;;4126:36:7;;;4239:34;;;4262:10;4239:34;;;;;;;;;;;;;3782:498;:::o;901:231:20:-;1032:7;1062:63;;;;;;;;;;;;;;-1:-1:-1;;;1062:63:20;;;1106:8;1116:7;1095:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1062:13;:63::i;:::-;1055:70;901:231;-1:-1:-1;;;901:231:20:o;2423:205:7:-;2498:4;2514:32;2549:19;:17;:19::i;:::-;-1:-1:-1;;;;;2585:36:7;;;;:22;:36;;;;;;;;-1:-1:-1;;2585:36:7;;;;;;;2423:205::o;2702:209::-;1031:23:13;1043:10;1031:11;:23::i;:::-;1023:51;;;;;-1:-1:-1;;;1023:51:13;;;;;;;;;;;;-1:-1:-1;;;1023:51:13;;;;;;;;;;;;;;;2765:32:7::1;2800:19;:17;:19::i;:::-;2829:21;::::0;::::1;:36:::0;;-1:-1:-1;;;;;;2829:36:7::1;::::0;;2880:24:::1;::::0;2765:54;;-1:-1:-1;2880:24:7::1;::::0;2861:3:::1;::::0;2880:24:::1;1084:1:13;2702:209:7:o:0;2917:303::-;1031:23:13;1043:10;1031:11;:23::i;:::-;1023:51;;;;;-1:-1:-1;;;1023:51:13;;;;;;;;;;;;-1:-1:-1;;;1023:51:13;;;;;;;;;;;;;;;3002:32:7::1;3037:19;:17;:19::i;:::-;3002:54;;3075:24;3087:11;3075;:24::i;:::-;3074:25;3066:54;;;::::0;;-1:-1:-1;;;3066:54:7;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;3066:54:7;;;;;;;;;;;;;::::1;;3130:21;::::0;::::1;:35:::0;;-1:-1:-1;;;;;3130:35:7;::::1;-1:-1:-1::0;;;;;;3130:35:7;;::::1;::::0;::::1;::::0;;;3180:33:::1;::::0;;;;;;::::1;::::0;;;;::::1;::::0;;::::1;1084:1:13;2917:303:7::0;:::o;2465:155:22:-;2538:4;2562:24;2578:7;2562:15;:24::i;:::-;:50;;;;2590:22;2604:7;2590:13;:22::i;1032:588:5:-;1120:16;1112:54;;;;;-1:-1:-1;;;1112:54:5;;;;;;;;;;;;-1:-1:-1;;;1112:54:5;;;;;;;;;;;;;;;1292:6:11;1240:33:5;;;;1322;;;1315:41;;;;1393:10;1374:15;:29;;1366:63;;;;;-1:-1:-1;;;1366:63:5;;;;;;;;;;;;-1:-1:-1;;;1366:63:5;;;;;;;;;;;;;;;1580:12;;1567:10;:25;1559:54;;;;;-1:-1:-1;;;1559:54:5;;;;;;;;;;;;-1:-1:-1;;;1559:54:5;;;;;;;;;;;;;;;1032:588;;:::o;1626:213::-;964:10:12;:8;:10::i;:::-;963:11;955:39;;;;;-1:-1:-1;;;955:39:12;;;;;;;;;;;;-1:-1:-1;;;955:39:12;;;;;;;;;;;;;;;1697:15:5::1;1514:8:11;1697:32:5;1682:12;:47:::0;1765:11:::1;:18:::0;;-1:-1:-1;;;;1765:18:5::1;-1:-1:-1::0;;;1765:18:5::1;::::0;;1821:11:::1;::::0;::::1;::::0;1765:18;;1821:11:::1;1626:213::o:0;4337:402:7:-;1031:23:13;1043:10;1031:11;:23::i;:::-;1023:51;;;;;-1:-1:-1;;;1023:51:13;;;;;;;;;;;;-1:-1:-1;;;1023:51:13;;;;;;;;;;;;;;;4432:10:7::1;-1:-1:-1::0;;;;;4432:32:7;::::1;;;4424:65;;;::::0;;-1:-1:-1;;;4424:65:7;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;4424:65:7;;;;;;;;;;;;;::::1;;4499:32;4534:19;:17;:19::i;:::-;4499:54;;4571:31;4583:18;4571:11;:31::i;:::-;4563:56;;;::::0;;-1:-1:-1;;;4563:56:7;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;4563:56:7;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;4629:42:7;::::1;4674:5;4629:42:::0;;;::::1;::::0;;;;;;;;:50;;-1:-1:-1;;4629:50:7::1;::::0;;4694:38;;;;;;;::::1;::::0;;;;;;;;::::1;1084:1:13;4337:402:7::0;:::o;1849:198:10:-;1924:14;1959:19;1969:8;1959:9;:19::i;:::-;1950:28;-1:-1:-1;;;;;;1996:22:10;;1988:52;;;;;-1:-1:-1;;;1988:52:10;;;;;;;;;;;;-1:-1:-1;;;1988:52:10;;;;;;;;;;;;;;1830:237:20;1998:62;2012:41;2035:8;2045:7;2012:22;:41::i;:::-;2055:4;1998:13;:62::i;2647:264:24:-;2706:4;;-1:-1:-1;;;;;;;;;2785:8:24;-1:-1:-1;;;;;;;;;2763:8:24;2753;2746:37;2739:66;2722:83;-1:-1:-1;2822:82:24;-1:-1:-1;;;;;;;;;1989:65:11;-1:-1:-1;;;;;;;;;2863:8:24;2855:6;2848:35;2841:62;2822:18;:82::i;1369:1348:2:-;1552:7;-1:-1:-1;;;;;;;;;;;1552:7:2;1530:18;:29;1522:62;;;;;-1:-1:-1;;;1522:62:2;;;;;;;;;;;;-1:-1:-1;;;1522:62:2;;;;;;;;;;;;;;;1608:1;1603;:6;;1602:26;;;;;-1:-1:-1;;;;;;;;;;;1615:1:2;:12;1602:26;1594:53;;;;;-1:-1:-1;;;1594:53:2;;;;;;;;;;;;-1:-1:-1;;;1594:53:2;;;;;;;;;;;;;;;1657:9;1669:18;:1;-1:-1:-1;;;;;;;;;;;1669:8:2;:18::i;:::-;1657:30;;1711:1;1706;:6;;1705:45;;;;-1:-1:-1;;;;1718:31:2;;1705:45;1697:72;;;;;-1:-1:-1;;;1697:72:2;;;;;;;;;;;;-1:-1:-1;;;1697:72:2;;;;;;;;;;;;;;;1793:1;1788;:6;;1787:45;;;;-1:-1:-1;;;;1800:31:2;;1787:45;1779:72;;;;;-1:-1:-1;;;1779:72:2;;;;;;;;;;;;-1:-1:-1;;;1779:72:2;;;;;;;;;;;;;;;1944:10;-1:-1:-1;;;;;;;;;1997:4:2;-1:-1:-1;;;;;;;;;1977:4:2;1971;1964:31;1957:58;1944:71;-1:-1:-1;2029:10:2;-1:-1:-1;;;;;;;;;2055:4:2;2049;2042:31;2029:44;-1:-1:-1;;;;;;;;;;922:76:2;-1:-1:-1;;;;;;;;;2136:4:2;2132:2;2125:29;2118:56;2112:2;:62;2087:138;;;;;-1:-1:-1;;;2087:138:2;;;;;;;;;;;;-1:-1:-1;;;2087:138:2;;;;;;;;;;;;;;;-1:-1:-1;2275:11:2;;-1:-1:-1;2275:11:2;;;2362:53;:7;1199:65;1298:64;883:1;-1:-1:-1;;;;;;;;;2362:13:2;:53::i;:::-;2331:84;;-1:-1:-1;2331:84:2;-1:-1:-1;2431:12:2;;2461:39;:1;2469:4;2475;883:1;-1:-1:-1;;;;;;;;;2461:7:2;:39::i;:::-;2430:70;;-1:-1:-1;2430:70:2;-1:-1:-1;2528:48:2;:4;2539;2430:70;;883:1;-1:-1:-1;;;;;;;;;2528:10:2;:48::i;:::-;2515:61;;-1:-1:-1;2515:61:2;-1:-1:-1;2597:13:2;;-1:-1:-1;2616:37:2;;-1:-1:-1;2616:1:2;;-1:-1:-1;2515:61:2;;-1:-1:-1;2515:61:2;883:1;-1:-1:-1;;;;;;;;;2616:7:2;:37::i;:::-;2596:57;;;2681:1;2672:5;:10;2664:46;;;;;-1:-1:-1;;;2664:46:2;;;;;;;;;;;;-1:-1:-1;;;2664:46:2;;;;;;;;;;;;;;;1369:1348;;;;;;;;;:::o;2562:155:17:-;2623:28;2670:14;2685:24;;;;;;;;;;;;;;;;;2670:40;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;2670:40:17;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;2670:40:17;;;;;;;;;;;;;;;;-1:-1:-1;2670:40:17;;;;;;;;;;;2562:155;-1:-1:-1;;;2562:155:17:o;3539:237:7:-;3608:24;3620:11;3608;:24::i;:::-;3607:25;3599:54;;;;;-1:-1:-1;;;3599:54:7;;;;;;;;;;;;-1:-1:-1;;;3599:54:7;;;;;;;;;;;;;;;3663:32;3698:19;:17;:19::i;:::-;-1:-1:-1;;;;;3727:35:7;;;:22;:35;;;;;;;;-1:-1:-1;3727:35:7;;;:42;;-1:-1:-1;;3727:42:7;3765:4;3727:42;;;3539:237::o;855:250:0:-;988:18;1062:10;1074:22;1045:52;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1045:52:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1045:52:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1045:52:0;;;;;;;;;;;;;-1:-1:-1;;1045:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1035:63;;;;;;1022:76;;855:250;;;;:::o;2626:207:22:-;2700:4;2803:23;:21;:23::i;:::-;2800:1;:26;2790:36;;;;2626:207;-1:-1:-1;2626:207:22:o;2839:363::-;2911:4;-1:-1:-1;;;2911:4:22;3098:21;:19;:21::i;:::-;3095:1;:24;3076:16;:43;3049:70;;3157:7;3137:16;:27;;:57;;;;;3178:16;3168:7;:26;3137:57;3129:66;2839:363;-1:-1:-1;;;;2839:363:22:o;1111:907:0:-;1591:11;1587:324;;;1623:9;1618:38;1642:5;1638:1;:9;1618:38;;;1649:3;;1618:38;;;;1587:324;;;1733:12;1711:35;;;;:21;:35;;;;;;2352:2:11;-1:-1:-1;1686:160:0;;;;;-1:-1:-1;;;1686:160:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;1882:12;1860:35;;;;:21;:35;;;;;:40;;1899:1;1860:40;;;1587:324;-1:-1:-1;1920:32:0;;;;:20;:32;;;;;1955:15;1920:50;;1980:14;:31;;;;;;;;;;;;1111:907::o;4578:152:24:-;4650:4;4678:45;4687:12;-1:-1:-1;;;4678:8:24;:45::i;:::-;4673:1;:50;;4578:152;-1:-1:-1;;4578:152:24:o;2551:387:3:-;2615:7;2638;;;;;:20;;;2655:3;2649:2;:9;;2638:20;:32;;;;-1:-1:-1;2662:8:3;;;2638:32;2630:59;;;;;-1:-1:-1;;;2630:59:3;;;;;;;;;;;;-1:-1:-1;;;2630:59:3;;;;;;;;;;;;;;;2695:9;2729:1;2748:3;2695:9;2772:147;2779:7;;2772:147;;2804:2;2800:1;:6;;;;;;2796:10;;2827:4;2873:3;2833:44;;;;;2866:3;2850:20;;;;;2860:4;2857:1;2850:20;2844:3;:26;2840:1;2833:44;2905:6;;;2901:10;;;;2814:64;;-1:-1:-1;2814:64:3;;-1:-1:-1;2772:147:3;;;-1:-1:-1;2932:1:3;;2551:387;-1:-1:-1;;;;;2551:387:3:o;8602:380::-;8724:7;8733;8782:10;8794;8806;8820:68;8834:2;8844;8854;8864:1;8873:3;8884;8820:6;:68::i;:::-;8781:107;;;;;;8927:50;8943:2;8953;8963;8973:3;8927:8;:50::i;:::-;8920:57;;;;;;;8602:380;;;;;;;;:::o;6898:723::-;7042:7;7051;7068:6;7084;7100;7159:3;7154;:8;7150:381;;;7217:3;7200:21;;;;;7212:3;7207;7200:21;7196:202;;7245:1;7248;7238:12;;;;;;;;;7196:202;7306:83;7327:3;7342;7357:1;7370:3;7385;7306:9;:83::i;:::-;7294:95;;-1:-1:-1;7294:95:3;-1:-1:-1;7294:95:3;-1:-1:-1;7150:381:3;;;7430:94;7446:3;7459;7472:1;7483:3;7496;7509:1;7520:3;7430:6;:94::i;:::-;7418:106;;-1:-1:-1;7418:106:3;-1:-1:-1;7418:106:3;-1:-1:-1;7150:381:3;7569:47;7585:1;7594;7603;7612:3;7569:8;:47::i;:::-;7562:54;;;;;;;6898:723;;;;;;;;;;:::o;4155:417:24:-;4228:7;4328:12;4342:23;4377:1;-1:-1:-1;;;;;4369:21:24;4415:4;4421;4427;4433;4439:8;-1:-1:-1;;;;;;;;;4404:55:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4369:100;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4369:100:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4327:142;;;;4487:7;4503:10;4479:36;;;;;-1:-1:-1;;;4479:36:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4543:10;4532:33;;;;;;;;;;;;;;;-1:-1:-1;4532:33:24;;4155:417;-1:-1:-1;;;;;4155:417:24:o;12816:752:3:-;12956:7;;;13038;13034:47;;-1:-1:-1;13063:2:3;;-1:-1:-1;13067:2:3;;-1:-1:-1;13071:2:3;13055:19;;13034:47;13107:2;13087:17;;13168:1;13208:331;13215:14;;13208:331;;13256:1;13244:13;;13243:20;13239:166;;13290:106;13308:2;13322;13336;13350;13364;13378;13392:3;13290:6;:106::i;:::-;13275:121;;-1:-1:-1;13275:121:3;-1:-1:-1;13275:121:3;-1:-1:-1;13239:166:3;13436:1;13424:9;:13;13412:25;;13460:72;13479:2;13491;13503;13515:3;13528;13460:9;:72::i;:::-;13445:87;;-1:-1:-1;13445:87:3;-1:-1:-1;13445:87:3;-1:-1:-1;13208:331:3;;;13552:2;;-1:-1:-1;13556:2:3;-1:-1:-1;13560:2:3;-1:-1:-1;;12816:752:3;;;;;;;;;;;:::o;4223:338::-;4332:7;4341;4358:12;4373:15;4380:2;4384:3;4373:6;:15::i;:::-;4358:30;;4394:13;4429:3;4410:23;;;;;4423:4;4417;4410:23;4394:39;;4439:10;4470:3;4452:22;;;;;4463:5;4459:2;4452:22;4439:35;;4480:10;4530:3;4493:41;;;;;4524:3;4504:24;;;;;4517:5;4511:4;4504:24;4500:2;4493:41;4549:2;;;;-1:-1:-1;4223:338:3;;-1:-1:-1;;;;;;;;4223:338:3:o;11275:1244::-;11402:7;;;11441;11437:38;;-1:-1:-1;11464:2:3;;-1:-1:-1;11468:2:3;;-1:-1:-1;11472:2:3;11456:19;;11437:38;11768:9;11795:3;11780:19;;;;;11791:2;11787;11780:19;11768:31;;11812:9;11839:3;11824:19;;;;;11835:2;11831;11824:19;11812:31;;11856:9;11883:3;11868:19;;;;;11879:2;11875;11868:19;11856:31;;11910:6;11949:3;11919:34;;;;;11943:3;11929:18;;;;;11940:1;11936:2;11929:18;11926:1;11919:34;11910:43;;11968:6;12040:3;11977:67;;;;;12034:3;12003:35;;;;;12028:3;12015:17;;;;;12025:1;12022;12015:17;12010:3;12003:35;11997:3;11984:17;;;;;11994:1;11991;11984:17;11977:67;11968:76;;12290:3;12239:55;;;;;12284:3;12271:17;;;;;12281:1;12278;12271:17;12265:3;:23;12259:3;12246:17;;;;;12256:1;12253;12246:17;12239:55;12235:59;;12422:3;12333:93;;;;;12416:3;12387:33;;;;;12410:3;12397:17;;;;;12407:1;12404;12397:17;12394:1;12387:33;12381:3;:39;12375:3;12340:39;;;;;12369:3;12350:23;;;;;12366:1;12360:3;:7;12357:1;12350:23;12347:1;12340:39;12333:93;12329:97;;12487:3;12456:35;;;;;12481:3;12466:19;;;;;12477:2;12473;12466:19;12463:1;12456:35;12506:1;;-1:-1:-1;12509:1:3;;-1:-1:-1;12452:39:3;;-1:-1:-1;;;;11275:1244:3;;;;;;;;;;:::o;9349:1655::-;9510:7;;;9549:6;;:16;;;;-1:-1:-1;9559:6:3;;9549:16;9545:50;;;-1:-1:-1;9581:3:3;;-1:-1:-1;9586:3:3;;-1:-1:-1;9591:3:3;9573:22;;9545:50;9605:6;;:16;;;;-1:-1:-1;9615:6:3;;9605:16;9601:50;;;-1:-1:-1;9637:3:3;;-1:-1:-1;9642:3:3;;-1:-1:-1;9647:3:3;9629:22;;9601:50;9791:17;;:::i;:::-;9865:3;9848:21;;;;;9860:3;9855;9848:21;9840:29;;9902:3;;9883:23;;;;9895:5;;9890:3;9883:23;9875:5;;;:31;9937:3;;9920:21;;;;9932:3;9927;9920:21;9912:5;;;:29;9974:3;;9955:23;;;;9967:5;;;;9962:3;9955:23;9947:5;;;:31;10007:135;;;;;;;;;;10039:3;;10020:23;;;;10032:5;;;;10027:3;10020:23;10007:135;;;;10070:3;10051:23;;;;;10063:5;;;;10058:3;10051:23;10007:135;;;;10101:3;10082:23;;;;;10094:5;;10089:3;10082:23;10007:135;;;;10132:3;10113:23;;;;;10125:5;;;;10120:3;10113:23;10007:135;;10249:5;;;;10240;;10007:135;;-1:-1:-1;10240:14:3;;;:32;;-1:-1:-1;10267:5:3;;;;;10258;;;:14;;10240:32;10232:75;;;;;-1:-1:-1;;;10232:75:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;10314:17;;:::i;:::-;10380:3;10353:31;;;;;10373:5;;10360;;;;10367:11;;;;10353:31;10345:39;;10433:3;;10406:31;;;;10426:5;;;;10413;;;;10420:11;;;;10406:31;10398:5;;;:39;10482:3;;10461:25;;;;10475:5;;;10461:25;10453:5;;;:33;10532:3;;10511:25;;;;10525:5;;10518;;;;10511:25;10503:5;;;:33;10572:10;10632:3;;10585:51;;;;10625:5;;;;10619:11;;:3;;10592:25;;;;10606:5;;;;;10592:25;10585:51;10572:64;;10707:3;10647:64;;;;;10701:3;10664:41;;;;;10695:3;10674:25;;;;;10688:5;;;;10681;;10674:25;10671:1;10664:41;10658:3;:47;10654:2;10647:64;10642:69;;10755:10;10832:3;10768:68;;;;;10826:3;10782:48;;;;;10822:2;10816:3;:8;10810:3;10789:25;;;;;10803:5;;;;10796;;10789:25;10782:48;10775:5;;;;10768:68;10755:81;;10891:3;10847:48;;;;;10885:3;10864:25;;;;;10878:5;;;;;10871;;;10864:25;10858:3;:31;10854:2;10847:48;10842:53;;10921:10;10971:3;10934:41;;;;;10965:3;10948:21;;;;;10960:3;10955;10948:21;10941:5;;10934:41;10988:2;;-1:-1:-1;10992:2:3;;-1:-1:-1;10921:54:3;;-1:-1:-1;;;;9349:1655:3;;;;;;;;;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;:::o

Swarm Source

ipfs://2a6988e2bd31c7b7a88d91f948bb5865e867cf9778e3a2decf940e6c404e1f79

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.