ETH Price: $1,972.82 (+0.15%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Update Policy Se...141792862022-02-10 16:04:021472 days ago1644509042IN
Enzyme Finance: Policy Manager
0 ETH0.01477344146.28767788
Update Policy Se...141648562022-02-08 10:18:231474 days ago1644315503IN
Enzyme Finance: Policy Manager
0 ETH0.0068857868.18348589
Update Policy Se...141646932022-02-08 9:42:561474 days ago1644313376IN
Enzyme Finance: Policy Manager
0 ETH0.0049788149.30056902
Update Policy Se...141580912022-02-07 9:20:121475 days ago1644225612IN
Enzyme Finance: Policy Manager
0 ETH0.0117510279.96017968
Update Policy Se...141332382022-02-03 13:17:221479 days ago1643894242IN
Enzyme Finance: Policy Manager
0 ETH0.0061376860.77579145
Update Policy Se...141331352022-02-03 12:57:521479 days ago1643893072IN
Enzyme Finance: Policy Manager
0 ETH0.0085000884.16844135
Update Policy Se...141330352022-02-03 12:31:291479 days ago1643891489IN
Enzyme Finance: Policy Manager
0 ETH0.0079978479.19519973
Update Policy Se...140970422022-01-28 23:06:011485 days ago1643411161IN
Enzyme Finance: Policy Manager
0 ETH0.01893344187.48024973
Update Policy Se...140819212022-01-26 14:51:091487 days ago1643208669IN
Enzyme Finance: Policy Manager
0 ETH0.01166393115.46967646
Update Policy Se...140814452022-01-26 13:09:491487 days ago1643202589IN
Enzyme Finance: Policy Manager
0 ETH0.0093134692.22252139
Update Policy Se...140762172022-01-25 18:00:061488 days ago1643133606IN
Enzyme Finance: Policy Manager
0 ETH0.01709267169.21264019
Update Policy Se...140744642022-01-25 11:21:111488 days ago1643109671IN
Enzyme Finance: Policy Manager
0 ETH0.0080400979.59468113
Update Policy Se...140721792022-01-25 2:43:231489 days ago1643078603IN
Enzyme Finance: Policy Manager
0 ETH0.007478874.03802284
Update Policy Se...140430072022-01-20 14:36:591493 days ago1642689419IN
Enzyme Finance: Policy Manager
0 ETH0.0117410779.89244432
Update Policy Se...140362992022-01-19 13:42:231494 days ago1642599743IN
Enzyme Finance: Policy Manager
0 ETH0.0092324991.39903369
Update Policy Se...140346152022-01-19 7:27:241495 days ago1642577244IN
Enzyme Finance: Policy Manager
0 ETH0.0096163195.1987661
Update Policy Se...140261072022-01-17 23:47:361496 days ago1642463256IN
Enzyme Finance: Policy Manager
0 ETH0.00572086113.01590374
Update Policy Se...139909482022-01-12 13:22:471501 days ago1641993767IN
Enzyme Finance: Policy Manager
0 ETH0.0127094125.81952188
Update Policy Se...139845262022-01-11 13:34:591502 days ago1641908099IN
Enzyme Finance: Policy Manager
0 ETH0.01354843134.14159018
Disable Policy F...139844662022-01-11 13:21:381502 days ago1641907298IN
Enzyme Finance: Policy Manager
0 ETH0.00560673120.33162084
Update Policy Se...139447802022-01-05 9:56:391508 days ago1641376599IN
Enzyme Finance: Policy Manager
0 ETH0.0115708278.73397307
Update Policy Se...139249822022-01-02 8:35:321512 days ago1641112532IN
Enzyme Finance: Policy Manager
0 ETH0.0063380862.74526893
Update Policy Se...139197872022-01-01 13:23:081512 days ago1641043388IN
Enzyme Finance: Policy Manager
0 ETH0.0059414658.82582367
Update Policy Se...139138392021-12-31 15:10:371513 days ago1640963437IN
Enzyme Finance: Policy Manager
0 ETH0.0080419968.08731277
Update Policy Se...139078832021-12-30 16:56:401514 days ago1640883400IN
Enzyme Finance: Policy Manager
0 ETH0.03505293123.07134407
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
PolicyManager

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, GNU GPLv3 license
// SPDX-License-Identifier: GPL-3.0

/*
    This file is part of the Enzyme Protocol.

    (c) Enzyme Council <council@enzyme.finance>

    For the full license information, please view the LICENSE
    file that was distributed with this source code.
*/

pragma solidity 0.6.12;
pragma experimental ABIEncoderV2;

import "@openzeppelin/contracts/utils/EnumerableSet.sol";
import "../../core/fund/vault/IVault.sol";
import "../utils/ExtensionBase.sol";
import "../utils/FundDeployerOwnerMixin.sol";
import "./IPolicy.sol";
import "./IPolicyManager.sol";

/// @title PolicyManager Contract
/// @author Enzyme Council <security@enzyme.finance>
/// @notice Manages policies for funds
contract PolicyManager is IPolicyManager, ExtensionBase, FundDeployerOwnerMixin {
    using EnumerableSet for EnumerableSet.AddressSet;

    event PolicyDeregistered(address indexed policy, string indexed identifier);

    event PolicyDisabledForFund(address indexed comptrollerProxy, address indexed policy);

    event PolicyEnabledForFund(
        address indexed comptrollerProxy,
        address indexed policy,
        bytes settingsData
    );

    event PolicyRegistered(
        address indexed policy,
        string indexed identifier,
        PolicyHook[] implementedHooks
    );

    EnumerableSet.AddressSet private registeredPolicies;
    mapping(address => mapping(PolicyHook => bool)) private policyToHookToIsImplemented;
    mapping(address => EnumerableSet.AddressSet) private comptrollerProxyToPolicies;

    modifier onlyBuySharesHooks(address _policy) {
        require(
            !policyImplementsHook(_policy, PolicyHook.PreCallOnIntegration) &&
                !policyImplementsHook(_policy, PolicyHook.PostCallOnIntegration),
            "onlyBuySharesHooks: Disallowed hook"
        );
        _;
    }

    modifier onlyEnabledPolicyForFund(address _comptrollerProxy, address _policy) {
        require(
            policyIsEnabledForFund(_comptrollerProxy, _policy),
            "onlyEnabledPolicyForFund: Policy not enabled"
        );
        _;
    }

    constructor(address _fundDeployer) public FundDeployerOwnerMixin(_fundDeployer) {}

    // EXTERNAL FUNCTIONS

    /// @notice Validates and initializes policies as necessary prior to fund activation
    /// @param _isMigratedFund True if the fund is migrating to this release
    /// @dev Caller is expected to be a valid ComptrollerProxy, but there isn't a need to validate.
    function activateForFund(bool _isMigratedFund) external override {
        address vaultProxy = __setValidatedVaultProxy(msg.sender);

        // Policies must assert that they are congruent with migrated vault state
        if (_isMigratedFund) {
            address[] memory enabledPolicies = getEnabledPoliciesForFund(msg.sender);
            for (uint256 i; i < enabledPolicies.length; i++) {
                __activatePolicyForFund(msg.sender, vaultProxy, enabledPolicies[i]);
            }
        }
    }

    /// @notice Deactivates policies for a fund by destroying storage
    function deactivateForFund() external override {
        delete comptrollerProxyToVaultProxy[msg.sender];

        for (uint256 i = comptrollerProxyToPolicies[msg.sender].length(); i > 0; i--) {
            comptrollerProxyToPolicies[msg.sender].remove(
                comptrollerProxyToPolicies[msg.sender].at(i - 1)
            );
        }
    }

    /// @notice Disables a policy for a fund
    /// @param _comptrollerProxy The ComptrollerProxy of the fund
    /// @param _policy The policy address to disable
    function disablePolicyForFund(address _comptrollerProxy, address _policy)
        external
        onlyBuySharesHooks(_policy)
        onlyEnabledPolicyForFund(_comptrollerProxy, _policy)
    {
        __validateIsFundOwner(getVaultProxyForFund(_comptrollerProxy), msg.sender);

        comptrollerProxyToPolicies[_comptrollerProxy].remove(_policy);

        emit PolicyDisabledForFund(_comptrollerProxy, _policy);
    }

    /// @notice Enables a policy for a fund
    /// @param _comptrollerProxy The ComptrollerProxy of the fund
    /// @param _policy The policy address to enable
    /// @param _settingsData The encoded settings data with which to configure the policy
    /// @dev Disabling a policy does not delete fund config on the policy, so if a policy is
    /// disabled and then enabled again, its initial state will be the previous config. It is the
    /// policy's job to determine how to merge that config with the _settingsData param in this function.
    function enablePolicyForFund(
        address _comptrollerProxy,
        address _policy,
        bytes calldata _settingsData
    ) external onlyBuySharesHooks(_policy) {
        address vaultProxy = getVaultProxyForFund(_comptrollerProxy);
        __validateIsFundOwner(vaultProxy, msg.sender);

        __enablePolicyForFund(_comptrollerProxy, _policy, _settingsData);

        __activatePolicyForFund(_comptrollerProxy, vaultProxy, _policy);
    }

    /// @notice Enable policies for use in a fund
    /// @param _configData Encoded config data
    /// @dev Only called during init() on ComptrollerProxy deployment
    function setConfigForFund(bytes calldata _configData) external override {
        (address[] memory policies, bytes[] memory settingsData) = abi.decode(
            _configData,
            (address[], bytes[])
        );

        // Sanity check
        require(
            policies.length == settingsData.length,
            "setConfigForFund: policies and settingsData array lengths unequal"
        );

        // Enable each policy with settings
        for (uint256 i; i < policies.length; i++) {
            __enablePolicyForFund(msg.sender, policies[i], settingsData[i]);
        }
    }

    /// @notice Updates policy settings for a fund
    /// @param _comptrollerProxy The ComptrollerProxy of the fund
    /// @param _policy The Policy contract to update
    /// @param _settingsData The encoded settings data with which to update the policy config
    function updatePolicySettingsForFund(
        address _comptrollerProxy,
        address _policy,
        bytes calldata _settingsData
    ) external onlyBuySharesHooks(_policy) onlyEnabledPolicyForFund(_comptrollerProxy, _policy) {
        address vaultProxy = getVaultProxyForFund(_comptrollerProxy);
        __validateIsFundOwner(vaultProxy, msg.sender);

        IPolicy(_policy).updateFundSettings(_comptrollerProxy, vaultProxy, _settingsData);
    }

    /// @notice Validates all policies that apply to a given hook for a fund
    /// @param _comptrollerProxy The ComptrollerProxy of the fund
    /// @param _hook The PolicyHook for which to validate policies
    /// @param _validationData The encoded data with which to validate the filtered policies
    function validatePolicies(
        address _comptrollerProxy,
        PolicyHook _hook,
        bytes calldata _validationData
    ) external override {
        address vaultProxy = getVaultProxyForFund(_comptrollerProxy);
        address[] memory policies = getEnabledPoliciesForFund(_comptrollerProxy);
        for (uint256 i; i < policies.length; i++) {
            if (!policyImplementsHook(policies[i], _hook)) {
                continue;
            }

            require(
                IPolicy(policies[i]).validateRule(
                    _comptrollerProxy,
                    vaultProxy,
                    _hook,
                    _validationData
                ),
                string(
                    abi.encodePacked(
                        "Rule evaluated to false: ",
                        IPolicy(policies[i]).identifier()
                    )
                )
            );
        }
    }

    // PRIVATE FUNCTIONS

    /// @dev Helper to activate a policy for a fund
    function __activatePolicyForFund(
        address _comptrollerProxy,
        address _vaultProxy,
        address _policy
    ) private {
        IPolicy(_policy).activateForFund(_comptrollerProxy, _vaultProxy);
    }

    /// @dev Helper to set config and enable policies for a fund
    function __enablePolicyForFund(
        address _comptrollerProxy,
        address _policy,
        bytes memory _settingsData
    ) private {
        require(
            !policyIsEnabledForFund(_comptrollerProxy, _policy),
            "__enablePolicyForFund: policy already enabled"
        );
        require(policyIsRegistered(_policy), "__enablePolicyForFund: Policy is not registered");

        // Set fund config on policy
        if (_settingsData.length > 0) {
            IPolicy(_policy).addFundSettings(_comptrollerProxy, _settingsData);
        }

        // Add policy
        comptrollerProxyToPolicies[_comptrollerProxy].add(_policy);

        emit PolicyEnabledForFund(_comptrollerProxy, _policy, _settingsData);
    }

    /// @dev Helper to validate fund owner.
    /// Preferred to a modifier because allows gas savings if re-using _vaultProxy.
    function __validateIsFundOwner(address _vaultProxy, address _who) private view {
        require(
            _who == IVault(_vaultProxy).getOwner(),
            "Only the fund owner can call this function"
        );
    }

    ///////////////////////
    // POLICIES REGISTRY //
    ///////////////////////

    /// @notice Remove policies from the list of registered policies
    /// @param _policies Addresses of policies to be registered
    function deregisterPolicies(address[] calldata _policies) external onlyFundDeployerOwner {
        require(_policies.length > 0, "deregisterPolicies: _policies cannot be empty");

        for (uint256 i; i < _policies.length; i++) {
            require(
                policyIsRegistered(_policies[i]),
                "deregisterPolicies: policy is not registered"
            );

            registeredPolicies.remove(_policies[i]);

            emit PolicyDeregistered(_policies[i], IPolicy(_policies[i]).identifier());
        }
    }

    /// @notice Add policies to the list of registered policies
    /// @param _policies Addresses of policies to be registered
    function registerPolicies(address[] calldata _policies) external onlyFundDeployerOwner {
        require(_policies.length > 0, "registerPolicies: _policies cannot be empty");

        for (uint256 i; i < _policies.length; i++) {
            require(
                !policyIsRegistered(_policies[i]),
                "registerPolicies: policy already registered"
            );

            registeredPolicies.add(_policies[i]);

            // Store the hooks that a policy implements for later use.
            // Fronts the gas for calls to check if a hook is implemented, and guarantees
            // that the implementsHooks return value does not change post-registration.
            IPolicy policyContract = IPolicy(_policies[i]);
            PolicyHook[] memory implementedHooks = policyContract.implementedHooks();
            for (uint256 j; j < implementedHooks.length; j++) {
                policyToHookToIsImplemented[_policies[i]][implementedHooks[j]] = true;
            }

            emit PolicyRegistered(_policies[i], policyContract.identifier(), implementedHooks);
        }
    }

    ///////////////////
    // STATE GETTERS //
    ///////////////////

    /// @notice Get all registered policies
    /// @return registeredPoliciesArray_ A list of all registered policy addresses
    function getRegisteredPolicies()
        external
        view
        returns (address[] memory registeredPoliciesArray_)
    {
        registeredPoliciesArray_ = new address[](registeredPolicies.length());
        for (uint256 i; i < registeredPoliciesArray_.length; i++) {
            registeredPoliciesArray_[i] = registeredPolicies.at(i);
        }
    }

    /// @notice Get a list of enabled policies for a given fund
    /// @param _comptrollerProxy The ComptrollerProxy of the fund
    /// @return enabledPolicies_ An array of enabled policy addresses
    function getEnabledPoliciesForFund(address _comptrollerProxy)
        public
        view
        returns (address[] memory enabledPolicies_)
    {
        enabledPolicies_ = new address[](comptrollerProxyToPolicies[_comptrollerProxy].length());
        for (uint256 i; i < enabledPolicies_.length; i++) {
            enabledPolicies_[i] = comptrollerProxyToPolicies[_comptrollerProxy].at(i);
        }
    }

    /// @notice Checks if a policy implements a particular hook
    /// @param _policy The address of the policy to check
    /// @param _hook The PolicyHook to check
    /// @return implementsHook_ True if the policy implements the hook
    function policyImplementsHook(address _policy, PolicyHook _hook)
        public
        view
        returns (bool implementsHook_)
    {
        return policyToHookToIsImplemented[_policy][_hook];
    }

    /// @notice Check if a policy is enabled for the fund
    /// @param _comptrollerProxy The ComptrollerProxy of the fund to check
    /// @param _policy The address of the policy to check
    /// @return isEnabled_ True if the policy is enabled for the fund
    function policyIsEnabledForFund(address _comptrollerProxy, address _policy)
        public
        view
        returns (bool isEnabled_)
    {
        return comptrollerProxyToPolicies[_comptrollerProxy].contains(_policy);
    }

    /// @notice Check whether a policy is registered
    /// @param _policy The address of the policy to check
    /// @return isRegistered_ True if the policy is registered
    function policyIsRegistered(address _policy) public view returns (bool isRegistered_) {
        return registeredPolicies.contains(_policy);
    }
}

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;

        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping (bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) { // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.

            bytes32 lastvalue = set._values[lastIndex];

            // Move the last value to the index where the value to delete is
            set._values[toDeleteIndex] = lastvalue;
            // Update the index for the moved value
            set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        require(set._values.length > index, "EnumerableSet: index out of bounds");
        return set._values[index];
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }


    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }
}

// SPDX-License-Identifier: GPL-3.0

/*
    This file is part of the Enzyme Protocol.

    (c) Enzyme Council <council@enzyme.finance>

    For the full license information, please view the LICENSE
    file that was distributed with this source code.
*/

pragma solidity 0.6.12;

/// @title IMigratableVault Interface
/// @author Enzyme Council <security@enzyme.finance>
/// @dev DO NOT EDIT CONTRACT
interface IMigratableVault {
    function canMigrate(address _who) external view returns (bool canMigrate_);

    function init(
        address _owner,
        address _accessor,
        string calldata _fundName
    ) external;

    function setAccessor(address _nextAccessor) external;

    function setVaultLib(address _nextVaultLib) external;
}

// SPDX-License-Identifier: GPL-3.0

/*
    This file is part of the Enzyme Protocol.

    (c) Enzyme Council <council@enzyme.finance>

    For the full license information, please view the LICENSE
    file that was distributed with this source code.
*/

pragma solidity 0.6.12;

/// @title IFundDeployer Interface
/// @author Enzyme Council <security@enzyme.finance>
interface IFundDeployer {
    enum ReleaseStatus {PreLaunch, Live, Paused}

    function getOwner() external view returns (address);

    function getReleaseStatus() external view returns (ReleaseStatus);

    function isRegisteredVaultCall(address, bytes4) external view returns (bool);
}

// SPDX-License-Identifier: GPL-3.0

/*
    This file is part of the Enzyme Protocol.

    (c) Enzyme Council <council@enzyme.finance>

    For the full license information, please view the LICENSE
    file that was distributed with this source code.
*/

pragma solidity 0.6.12;

/// @title IComptroller Interface
/// @author Enzyme Council <security@enzyme.finance>
interface IComptroller {
    enum VaultAction {
        None,
        BurnShares,
        MintShares,
        TransferShares,
        ApproveAssetSpender,
        WithdrawAssetTo,
        AddTrackedAsset,
        RemoveTrackedAsset
    }

    function activate(address, bool) external;

    function calcGav(bool) external returns (uint256, bool);

    function calcGrossShareValue(bool) external returns (uint256, bool);

    function callOnExtension(
        address,
        uint256,
        bytes calldata
    ) external;

    function configureExtensions(bytes calldata, bytes calldata) external;

    function destruct() external;

    function getDenominationAsset() external view returns (address);

    function getVaultProxy() external view returns (address);

    function init(address, uint256) external;

    function permissionedVaultAction(VaultAction, bytes calldata) external;
}

// SPDX-License-Identifier: GPL-3.0

/*
    This file is part of the Enzyme Protocol.

    (c) Enzyme Council <council@enzyme.finance>

    For the full license information, please view the LICENSE
    file that was distributed with this source code.
*/

pragma solidity 0.6.12;

import "../../../../persistent/utils/IMigratableVault.sol";

/// @title IVault Interface
/// @author Enzyme Council <security@enzyme.finance>
interface IVault is IMigratableVault {
    function addTrackedAsset(address) external;

    function approveAssetSpender(
        address,
        address,
        uint256
    ) external;

    function burnShares(address, uint256) external;

    function callOnContract(address, bytes calldata) external;

    function getAccessor() external view returns (address);

    function getOwner() external view returns (address);

    function getTrackedAssets() external view returns (address[] memory);

    function isTrackedAsset(address) external view returns (bool);

    function mintShares(address, uint256) external;

    function removeTrackedAsset(address) external;

    function transferShares(
        address,
        address,
        uint256
    ) external;

    function withdrawAssetTo(
        address,
        address,
        uint256
    ) external;
}

// SPDX-License-Identifier: GPL-3.0

/*
    This file is part of the Enzyme Protocol.

    (c) Enzyme Council <council@enzyme.finance>

    For the full license information, please view the LICENSE
    file that was distributed with this source code.
*/

pragma solidity 0.6.12;

/// @title IExtension Interface
/// @author Enzyme Council <security@enzyme.finance>
/// @notice Interface for all extensions
interface IExtension {
    function activateForFund(bool _isMigration) external;

    function deactivateForFund() external;

    function receiveCallFromComptroller(
        address _comptrollerProxy,
        uint256 _actionId,
        bytes calldata _callArgs
    ) external;

    function setConfigForFund(bytes calldata _configData) external;
}

// SPDX-License-Identifier: GPL-3.0

/*
    This file is part of the Enzyme Protocol.

    (c) Enzyme Council <council@enzyme.finance>

    For the full license information, please view the LICENSE
    file that was distributed with this source code.
*/

pragma solidity 0.6.12;

import "./IPolicyManager.sol";

/// @title Policy Interface
/// @author Enzyme Council <security@enzyme.finance>
interface IPolicy {
    function activateForFund(address _comptrollerProxy, address _vaultProxy) external;

    function addFundSettings(address _comptrollerProxy, bytes calldata _encodedSettings) external;

    function identifier() external pure returns (string memory identifier_);

    function implementedHooks()
        external
        view
        returns (IPolicyManager.PolicyHook[] memory implementedHooks_);

    function updateFundSettings(
        address _comptrollerProxy,
        address _vaultProxy,
        bytes calldata _encodedSettings
    ) external;

    function validateRule(
        address _comptrollerProxy,
        address _vaultProxy,
        IPolicyManager.PolicyHook _hook,
        bytes calldata _encodedArgs
    ) external returns (bool isValid_);
}

File 9 of 11 : IPolicyManager.sol
// SPDX-License-Identifier: GPL-3.0

/*
    This file is part of the Enzyme Protocol.

    (c) Enzyme Council <council@enzyme.finance>

    For the full license information, please view the LICENSE
    file that was distributed with this source code.
*/

pragma solidity 0.6.12;
pragma experimental ABIEncoderV2;

/// @title PolicyManager Interface
/// @author Enzyme Council <security@enzyme.finance>
/// @notice Interface for the PolicyManager
interface IPolicyManager {
    enum PolicyHook {
        BuySharesSetup,
        PreBuyShares,
        PostBuyShares,
        BuySharesCompleted,
        PreCallOnIntegration,
        PostCallOnIntegration
    }

    function validatePolicies(
        address,
        PolicyHook,
        bytes calldata
    ) external;
}

// SPDX-License-Identifier: GPL-3.0

/*
    This file is part of the Enzyme Protocol.

    (c) Enzyme Council <council@enzyme.finance>

    For the full license information, please view the LICENSE
    file that was distributed with this source code.
*/

pragma solidity 0.6.12;

import "../../core/fund/comptroller/IComptroller.sol";
import "../../core/fund/vault/IVault.sol";
import "../IExtension.sol";

/// @title ExtensionBase Contract
/// @author Enzyme Council <security@enzyme.finance>
/// @notice Base class for an extension
abstract contract ExtensionBase is IExtension {
    mapping(address => address) internal comptrollerProxyToVaultProxy;

    /// @notice Allows extension to run logic during fund activation
    /// @dev Unimplemented by default, may be overridden.
    function activateForFund(bool) external virtual override {
        return;
    }

    /// @notice Allows extension to run logic during fund deactivation (destruct)
    /// @dev Unimplemented by default, may be overridden.
    function deactivateForFund() external virtual override {
        return;
    }

    /// @notice Receives calls from ComptrollerLib.callOnExtension()
    /// and dispatches the appropriate action
    /// @dev Unimplemented by default, may be overridden.
    function receiveCallFromComptroller(
        address,
        uint256,
        bytes calldata
    ) external virtual override {
        revert("receiveCallFromComptroller: Unimplemented for Extension");
    }

    /// @notice Allows extension to run logic during fund configuration
    /// @dev Unimplemented by default, may be overridden.
    function setConfigForFund(bytes calldata) external virtual override {
        return;
    }

    /// @dev Helper to validate a ComptrollerProxy-VaultProxy relation, which we store for both
    /// gas savings and to guarantee a spoofed ComptrollerProxy does not change getVaultProxy().
    /// Will revert without reason if the expected interfaces do not exist.
    function __setValidatedVaultProxy(address _comptrollerProxy)
        internal
        returns (address vaultProxy_)
    {
        require(
            comptrollerProxyToVaultProxy[_comptrollerProxy] == address(0),
            "__setValidatedVaultProxy: Already set"
        );

        vaultProxy_ = IComptroller(_comptrollerProxy).getVaultProxy();
        require(vaultProxy_ != address(0), "__setValidatedVaultProxy: Missing vaultProxy");

        require(
            _comptrollerProxy == IVault(vaultProxy_).getAccessor(),
            "__setValidatedVaultProxy: Not the VaultProxy accessor"
        );

        comptrollerProxyToVaultProxy[_comptrollerProxy] = vaultProxy_;

        return vaultProxy_;
    }

    ///////////////////
    // STATE GETTERS //
    ///////////////////

    /// @notice Gets the verified VaultProxy for a given ComptrollerProxy
    /// @param _comptrollerProxy The ComptrollerProxy of the fund
    /// @return vaultProxy_ The VaultProxy of the fund
    function getVaultProxyForFund(address _comptrollerProxy)
        public
        view
        returns (address vaultProxy_)
    {
        return comptrollerProxyToVaultProxy[_comptrollerProxy];
    }
}

File 11 of 11 : FundDeployerOwnerMixin.sol
// SPDX-License-Identifier: GPL-3.0

/*
    This file is part of the Enzyme Protocol.

    (c) Enzyme Council <council@enzyme.finance>

    For the full license information, please view the LICENSE
    file that was distributed with this source code.
*/

pragma solidity 0.6.12;

import "../../core/fund-deployer/IFundDeployer.sol";

/// @title FundDeployerOwnerMixin Contract
/// @author Enzyme Council <security@enzyme.finance>
/// @notice A mixin contract that defers ownership to the owner of FundDeployer
abstract contract FundDeployerOwnerMixin {
    address internal immutable FUND_DEPLOYER;

    modifier onlyFundDeployerOwner() {
        require(
            msg.sender == getOwner(),
            "onlyFundDeployerOwner: Only the FundDeployer owner can call this function"
        );
        _;
    }

    constructor(address _fundDeployer) public {
        FUND_DEPLOYER = _fundDeployer;
    }

    /// @notice Gets the owner of this contract
    /// @return owner_ The owner
    /// @dev Ownership is deferred to the owner of the FundDeployer contract
    function getOwner() public view returns (address owner_) {
        return IFundDeployer(FUND_DEPLOYER).getOwner();
    }

    ///////////////////
    // STATE GETTERS //
    ///////////////////

    /// @notice Gets the `FUND_DEPLOYER` variable
    /// @return fundDeployer_ The `FUND_DEPLOYER` variable value
    function getFundDeployer() external view returns (address fundDeployer_) {
        return FUND_DEPLOYER;
    }
}

Settings
{
  "evmVersion": "istanbul",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "details": {
      "constantOptimizer": true,
      "cse": true,
      "deduplicate": true,
      "jumpdestRemover": true,
      "orderLiterals": true,
      "peephole": true,
      "yul": false
    },
    "runs": 200
  },
  "remappings": [],
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_fundDeployer","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"policy","type":"address"},{"indexed":true,"internalType":"string","name":"identifier","type":"string"}],"name":"PolicyDeregistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"comptrollerProxy","type":"address"},{"indexed":true,"internalType":"address","name":"policy","type":"address"}],"name":"PolicyDisabledForFund","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"comptrollerProxy","type":"address"},{"indexed":true,"internalType":"address","name":"policy","type":"address"},{"indexed":false,"internalType":"bytes","name":"settingsData","type":"bytes"}],"name":"PolicyEnabledForFund","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"policy","type":"address"},{"indexed":true,"internalType":"string","name":"identifier","type":"string"},{"indexed":false,"internalType":"enum IPolicyManager.PolicyHook[]","name":"implementedHooks","type":"uint8[]"}],"name":"PolicyRegistered","type":"event"},{"inputs":[{"internalType":"bool","name":"_isMigratedFund","type":"bool"}],"name":"activateForFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deactivateForFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_policies","type":"address[]"}],"name":"deregisterPolicies","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_comptrollerProxy","type":"address"},{"internalType":"address","name":"_policy","type":"address"}],"name":"disablePolicyForFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_comptrollerProxy","type":"address"},{"internalType":"address","name":"_policy","type":"address"},{"internalType":"bytes","name":"_settingsData","type":"bytes"}],"name":"enablePolicyForFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_comptrollerProxy","type":"address"}],"name":"getEnabledPoliciesForFund","outputs":[{"internalType":"address[]","name":"enabledPolicies_","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFundDeployer","outputs":[{"internalType":"address","name":"fundDeployer_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"owner_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRegisteredPolicies","outputs":[{"internalType":"address[]","name":"registeredPoliciesArray_","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_comptrollerProxy","type":"address"}],"name":"getVaultProxyForFund","outputs":[{"internalType":"address","name":"vaultProxy_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_policy","type":"address"},{"internalType":"enum IPolicyManager.PolicyHook","name":"_hook","type":"uint8"}],"name":"policyImplementsHook","outputs":[{"internalType":"bool","name":"implementsHook_","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_comptrollerProxy","type":"address"},{"internalType":"address","name":"_policy","type":"address"}],"name":"policyIsEnabledForFund","outputs":[{"internalType":"bool","name":"isEnabled_","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_policy","type":"address"}],"name":"policyIsRegistered","outputs":[{"internalType":"bool","name":"isRegistered_","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"receiveCallFromComptroller","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_policies","type":"address[]"}],"name":"registerPolicies","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_configData","type":"bytes"}],"name":"setConfigForFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_comptrollerProxy","type":"address"},{"internalType":"address","name":"_policy","type":"address"},{"internalType":"bytes","name":"_settingsData","type":"bytes"}],"name":"updatePolicySettingsForFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_comptrollerProxy","type":"address"},{"internalType":"enum IPolicyManager.PolicyHook","name":"_hook","type":"uint8"},{"internalType":"bytes","name":"_validationData","type":"bytes"}],"name":"validatePolicies","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a06040523480156200001157600080fd5b50604051620026163803806200261683398101604081905262000034916200005d565b60601b6001600160601b031916608052620000b2565b8051620000578162000098565b92915050565b6000602082840312156200007057600080fd5b60006200007e84846200004a565b949350505050565b60006001600160a01b03821662000057565b620000a38162000086565b8114620000af57600080fd5b50565b60805160601c612541620000d56000398061074652806109b752506125416000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638af6d89e116100a2578063a5c6e2b811610071578063a5c6e2b814610216578063bd8e959a14610236578063e8cf4d431461023e578063ee37ebcf14610251578063fa5d06e31461026457610116565b80638af6d89e146101d3578063961363d9146101f357806397c0ac87146101fb5780639c532bac1461020357610116565b806348f35209116100e957806348f352091461017f5780634ed28b3f1461019257806380d57063146101a5578063893d20e8146101b857806389cbe1d0146101c057610116565b80630442bad51461011b5780631bee801e1461013057806345d582e7146101435780634679034614610156575b600080fd5b61012e610129366004611900565b610277565b005b61012e61013e366004611933565b61043d565b61012e61015136600461182f565b610455565b6101696101643660046117eb565b610536565b60405161017691906121d0565b60405180910390f35b61012e61018d366004611869565b610557565b61012e6101a0366004611869565b6105ff565b61012e6101b3366004611a38565b6106e9565b610169610742565b61012e6101ce366004611a74565b6107da565b6101e66101e13660046117eb565b61085a565b6040516101769190612297565b6101e6610920565b6101696109b5565b61012e610211366004611966565b6109d9565b61022961022436600461182f565b610ce6565b60405161017691906122b9565b61012e610d11565b61022961024c3660046118d0565b610d8b565b61012e61025f366004611966565b610dd6565b6102296102723660046117eb565b610f96565b600061028285610536565b9050606061028f8661085a565b905060005b8151811015610434576102ba8282815181106102ac57fe5b602002602001015187610d8b565b6102c35761042c565b8181815181106102cf57fe5b60200260200101516001600160a01b0316635b8f1c5a88858989896040518663ffffffff1660e01b815260040161030a959493929190612231565b602060405180830381600087803b15801561032457600080fd5b505af1158015610338573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035c9190611a56565b82828151811061036857fe5b60200260200101516001600160a01b0316637998a1c46040518163ffffffff1660e01b815260040160006040518083038186803b1580156103a857600080fd5b505afa1580156103bc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526103e49190810190611aa9565b6040516020016103f491906121b9565b6040516020818303038152906040529061042a5760405162461bcd60e51b815260040161042191906122c7565b60405180910390fd5b505b600101610294565b50505050505050565b60405162461bcd60e51b815260040161042190612388565b80610461816004610d8b565b1580156104765750610474816005610d8b565b155b6104925760405162461bcd60e51b815260040161042190612368565b828261049e8282610ce6565b6104ba5760405162461bcd60e51b8152600401610421906123c8565b6104cc6104c686610536565b33610fa3565b6001600160a01b03851660009081526004602052604090206104ee9085611044565b50836001600160a01b0316856001600160a01b03167fd7b03d2e8be34a451c0a51c07755427856dd05d0343003f8a7ab0f1af52e96c560405160405180910390a35050505050565b6001600160a01b03808216600090815260208190526040902054165b919050565b82610563816004610d8b565b1580156105785750610576816005610d8b565b155b6105945760405162461bcd60e51b815260040161042190612368565b600061059f86610536565b90506105ab8133610fa3565b6105ec868686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061105992505050565b6105f7868287611180565b505050505050565b8261060b816004610d8b565b158015610620575061061e816005610d8b565b155b61063c5760405162461bcd60e51b815260040161042190612368565b84846106488282610ce6565b6106645760405162461bcd60e51b8152600401610421906123c8565b600061066f88610536565b905061067b8133610fa3565b6040516308945f1960e41b81526001600160a01b03881690638945f190906106ad908b9085908b908b906004016121f9565b600060405180830381600087803b1580156106c757600080fd5b505af11580156106db573d6000803e3d6000fd5b505050505050505050505050565b60006106f4336111dc565b9050811561073e5760606107073361085a565b905060005b815181101561073b57610733338484848151811061072657fe5b6020026020010151611180565b60010161070c565b50505b5050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b15801561079d57600080fd5b505afa1580156107b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d59190611811565b905090565b6060806107e9838501856119a7565b91509150805182511461080e5760405162461bcd60e51b815260040161042190612348565b60005b82518110156108535761084b3384838151811061082a57fe5b602002602001015184848151811061083e57fe5b6020026020010151611059565b600101610811565b5050505050565b6001600160a01b038116600090815260046020526040902060609061087e90611382565b6001600160401b038111801561089357600080fd5b506040519080825280602002602001820160405280156108bd578160200160208202803683370190505b50905060005b815181101561091a576001600160a01b03831660009081526004602052604090206108ee908261138d565b8282815181106108fa57fe5b6001600160a01b03909216602092830291909101909101526001016108c3565b50919050565b606061092c6001611382565b6001600160401b038111801561094157600080fd5b5060405190808252806020026020018201604052801561096b578160200160208202803683370190505b50905060005b81518110156109b15761098560018261138d565b82828151811061099157fe5b6001600160a01b0390921660209283029190910190910152600101610971565b5090565b7f000000000000000000000000000000000000000000000000000000000000000090565b6109e1610742565b6001600160a01b0316336001600160a01b031614610a115760405162461bcd60e51b815260040161042190612318565b80610a2e5760405162461bcd60e51b815260040161042190612338565b60005b81811015610ce157610a5d838383818110610a4857fe5b905060200201602081019061027291906117eb565b15610a7a5760405162461bcd60e51b815260040161042190612308565b610aa6838383818110610a8957fe5b9050602002016020810190610a9e91906117eb565b600190611399565b506000838383818110610ab557fe5b9050602002016020810190610aca91906117eb565b90506060816001600160a01b031663cbf54bb26040518163ffffffff1660e01b815260040160006040518083038186803b158015610b0757600080fd5b505afa158015610b1b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b439190810190611a04565b905060005b8151811015610beb57600160036000888888818110610b6357fe5b9050602002016020810190610b7891906117eb565b6001600160a01b03166001600160a01b031681526020019081526020016000206000848481518110610ba657fe5b60200260200101516005811115610bb957fe5b6005811115610bc457fe5b81526020810191909152604001600020805460ff1916911515919091179055600101610b48565b50816001600160a01b0316637998a1c46040518163ffffffff1660e01b815260040160006040518083038186803b158015610c2557600080fd5b505afa158015610c39573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c619190810190611aa9565b604051610c6e91906121a6565b6040518091039020858585818110610c8257fe5b9050602002016020810190610c9791906117eb565b6001600160a01b03167f7fc39bd4ad1acc50e51318d02e8590c304ae9c0060c220cc780ea18720745c5283604051610ccf91906122a8565b60405180910390a35050600101610a31565b505050565b6001600160a01b0382166000908152600460205260408120610d0890836113ae565b90505b92915050565b3360009081526020818152604080832080546001600160a01b031916905560049091528120610d3f90611382565b90505b8015610d8857336000908152600460205260409020610d7e90610d6990600019840161138d565b33600090815260046020526040902090611044565b5060001901610d42565b50565b6001600160a01b038216600090815260036020526040812081836005811115610db057fe5b6005811115610dbb57fe5b815260208101919091526040016000205460ff169392505050565b610dde610742565b6001600160a01b0316336001600160a01b031614610e0e5760405162461bcd60e51b815260040161042190612318565b80610e2b5760405162461bcd60e51b815260040161042190612358565b60005b81811015610ce157610e45838383818110610a4857fe5b610e615760405162461bcd60e51b8152600401610421906122f8565b610e8d838383818110610e7057fe5b9050602002016020810190610e8591906117eb565b600190611044565b50828282818110610e9a57fe5b9050602002016020810190610eaf91906117eb565b6001600160a01b0316637998a1c46040518163ffffffff1660e01b815260040160006040518083038186803b158015610ee757600080fd5b505afa158015610efb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f239190810190611aa9565b604051610f3091906121a6565b6040518091039020838383818110610f4457fe5b9050602002016020810190610f5991906117eb565b6001600160a01b03167f538f684b60a142c0b72b895be785c0aef10b373c6c5c4e8a7eb49baa244f64d360405160405180910390a3600101610e2e565b6000610d0b6001836113ae565b816001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b158015610fdc57600080fd5b505afa158015610ff0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110149190611811565b6001600160a01b0316816001600160a01b03161461073e5760405162461bcd60e51b815260040161042190612398565b6000610d08836001600160a01b0384166113c3565b6110638383610ce6565b156110805760405162461bcd60e51b8152600401610421906123a8565b61108982610f96565b6110a55760405162461bcd60e51b8152600401610421906123b8565b80511561110d57604051630f5f6b4f60e01b81526001600160a01b03831690630f5f6b4f906110da9086908590600401612277565b600060405180830381600087803b1580156110f457600080fd5b505af1158015611108573d6000803e3d6000fd5b505050505b6001600160a01b038316600090815260046020526040902061112f9083611399565b50816001600160a01b0316836001600160a01b03167faa4df4fe117c520783cfff01c11283496ff2999c77c2a9b800808251a9a0332a8360405161117391906122c7565b60405180910390a3505050565b604051630628da0b60e31b81526001600160a01b03821690633146d058906111ae90869086906004016121de565b600060405180830381600087803b1580156111c857600080fd5b505af1158015610434573d6000803e3d6000fd5b6001600160a01b03818116600090815260208190526040812054909116156112165760405162461bcd60e51b8152600401610421906122e8565b816001600160a01b031663c98091876040518163ffffffff1660e01b815260040160206040518083038186803b15801561124f57600080fd5b505afa158015611263573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112879190611811565b90506001600160a01b0381166112af5760405162461bcd60e51b815260040161042190612328565b806001600160a01b0316635a53e3486040518163ffffffff1660e01b815260040160206040518083038186803b1580156112e857600080fd5b505afa1580156112fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113209190611811565b6001600160a01b0316826001600160a01b0316146113505760405162461bcd60e51b815260040161042190612378565b6001600160a01b03918216600090815260208190526040902080546001600160a01b0319169282169290921790915590565b6000610d0b82611489565b6000610d08838361148d565b6000610d08836001600160a01b0384166114d2565b6000610d08836001600160a01b03841661151c565b6000818152600183016020526040812054801561147f57835460001980830191908101906000908790839081106113f657fe5b906000526020600020015490508087600001848154811061141357fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061144357fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610d0b565b6000915050610d0b565b5490565b815460009082106114b05760405162461bcd60e51b8152600401610421906122d8565b8260000182815481106114bf57fe5b9060005260206000200154905092915050565b60006114de838361151c565b61151457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610d0b565b506000610d0b565b60009081526001919091016020526040902054151590565b8035610d0b816124d8565b8051610d0b816124d8565b60008083601f84011261155c57600080fd5b5081356001600160401b0381111561157357600080fd5b60208301915083602082028301111561158b57600080fd5b9250929050565b600082601f8301126115a357600080fd5b81356115b66115b1826123fe565b6123d8565b915081818352602084019350602081019050838560208402820111156115db57600080fd5b60005b8381101561160757816115f18882611534565b84525060209283019291909101906001016115de565b5050505092915050565b600082601f83011261162257600080fd5b81356116306115b1826123fe565b81815260209384019390925082018360005b8381101561160757813586016116588882611735565b8452506020928301929190910190600101611642565b600082601f83011261167f57600080fd5b815161168d6115b1826123fe565b915081818352602084019350602081019050838560208402820111156116b257600080fd5b60005b8381101561160757816116c8888261178f565b84525060209283019291909101906001016116b5565b8035610d0b816124ec565b8051610d0b816124ec565b60008083601f84011261170657600080fd5b5081356001600160401b0381111561171d57600080fd5b60208301915083600182028301111561158b57600080fd5b600082601f83011261174657600080fd5b81356117546115b18261241e565b9150808252602083016020830185838301111561177057600080fd5b61177b83828461248c565b50505092915050565b8035610d0b816124f5565b8051610d0b816124f5565b600082601f8301126117ab57600080fd5b81516117b96115b18261241e565b915080825260208301602083018583830111156117d557600080fd5b61177b838284612498565b8035610d0b81612502565b6000602082840312156117fd57600080fd5b60006118098484611534565b949350505050565b60006020828403121561182357600080fd5b6000611809848461153f565b6000806040838503121561184257600080fd5b600061184e8585611534565b925050602061185f85828601611534565b9150509250929050565b6000806000806060858703121561187f57600080fd5b600061188b8787611534565b945050602061189c87828801611534565b93505060408501356001600160401b038111156118b857600080fd5b6118c4878288016116f4565b95989497509550505050565b600080604083850312156118e357600080fd5b60006118ef8585611534565b925050602061185f85828601611784565b6000806000806060858703121561191657600080fd5b60006119228787611534565b945050602061189c87828801611784565b6000806000806060858703121561194957600080fd5b60006119558787611534565b945050602061189c878288016117e0565b6000806020838503121561197957600080fd5b82356001600160401b0381111561198f57600080fd5b61199b8582860161154a565b92509250509250929050565b600080604083850312156119ba57600080fd5b82356001600160401b038111156119d057600080fd5b6119dc85828601611592565b92505060208301356001600160401b038111156119f857600080fd5b61185f85828601611611565b600060208284031215611a1657600080fd5b81516001600160401b03811115611a2c57600080fd5b6118098482850161166e565b600060208284031215611a4a57600080fd5b600061180984846116de565b600060208284031215611a6857600080fd5b600061180984846116e9565b60008060208385031215611a8757600080fd5b82356001600160401b03811115611a9d57600080fd5b61199b858286016116f4565b600060208284031215611abb57600080fd5b81516001600160401b03811115611ad157600080fd5b6118098482850161179a565b6000611ae98383611afd565b505060200190565b6000611ae98383611c16565b611b0681612458565b82525050565b6000611b178261244b565b611b21818561244f565b9350611b2c83612445565b8060005b83811015611b5a578151611b448882611add565b9750611b4f83612445565b925050600101611b30565b509495945050505050565b6000611b708261244b565b611b7a818561244f565b9350611b8583612445565b8060005b83811015611b5a578151611b9d8882611af1565b9750611ba883612445565b925050600101611b89565b611b0681612463565b6000611bc8838561244f565b9350611bd583858461248c565b611bde836124c4565b9093019392505050565b6000611bf38261244b565b611bfd818561244f565b9350611c0d818560208601612498565b611bde816124c4565b611b0681612481565b6000611c2a8261244b565b611c348185610552565b9350611c44818560208601612498565b9290920192915050565b6000611c5b60228361244f565b7f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e815261647360f01b602082015260400192915050565b6000611c9f60258361244f565b7f5f5f73657456616c6964617465645661756c7450726f78793a20416c726561648152641e481cd95d60da1b602082015260400192915050565b6000611ce6602c8361244f565b7f64657265676973746572506f6c69636965733a20706f6c696379206973206e6f81526b1d081c9959da5cdd195c995960a21b602082015260400192915050565b6000611d34602b8361244f565b7f7265676973746572506f6c69636965733a20706f6c69637920616c726561647981526a081c9959da5cdd195c995960aa1b602082015260400192915050565b6000611d8160498361244f565b7f6f6e6c7946756e644465706c6f7965724f776e65723a204f6e6c79207468652081527f46756e644465706c6f796572206f776e65722063616e2063616c6c207468697360208201526810333ab731ba34b7b760b91b604082015260600192915050565b6000611df2602c8361244f565b7f5f5f73657456616c6964617465645661756c7450726f78793a204d697373696e81526b67207661756c7450726f787960a01b602082015260400192915050565b6000611e40602b8361244f565b7f7265676973746572506f6c69636965733a205f706f6c69636965732063616e6e81526a6f7420626520656d70747960a81b602082015260400192915050565b6000611e8d60418361244f565b7f736574436f6e666967466f7246756e643a20706f6c696369657320616e64207381527f657474696e677344617461206172726179206c656e6774687320756e657175616020820152601b60fa1b604082015260600192915050565b6000611ef6602d8361244f565b7f64657265676973746572506f6c69636965733a205f706f6c696369657320636181526c6e6e6f7420626520656d70747960981b602082015260400192915050565b6000611f4560238361244f565b7f6f6e6c79427579536861726573486f6f6b733a20446973616c6c6f77656420688152626f6f6b60e81b602082015260400192915050565b6000611f8a601983610552565b7f52756c65206576616c756174656420746f2066616c73653a2000000000000000815260190192915050565b6000611fc360358361244f565b7f5f5f73657456616c6964617465645661756c7450726f78793a204e6f7420746881527432902b30bab63a283937bc3c9030b1b1b2b9b9b7b960591b602082015260400192915050565b600061201a60378361244f565b7f7265636569766543616c6c46726f6d436f6d7074726f6c6c65723a20556e696d81527f706c656d656e74656420666f7220457874656e73696f6e000000000000000000602082015260400192915050565b6000612079602a8361244f565b7f4f6e6c79207468652066756e64206f776e65722063616e2063616c6c207468698152693990333ab731ba34b7b760b11b602082015260400192915050565b60006120c5602d8361244f565b7f5f5f656e61626c65506f6c696379466f7246756e643a20706f6c69637920616c81526c1c9958591e48195b98589b1959609a1b602082015260400192915050565b6000612114602f8361244f565b7f5f5f656e61626c65506f6c696379466f7246756e643a20506f6c69637920697381526e081b9bdd081c9959da5cdd195c9959608a1b602082015260400192915050565b6000612165602c8361244f565b7f6f6e6c79456e61626c6564506f6c696379466f7246756e643a20506f6c69637981526b081b9bdd08195b98589b195960a21b602082015260400192915050565b60006121b28284611c1f565b9392505050565b60006121c482611f7d565b91506121b28284611c1f565b60208101610d0b8284611afd565b604081016121ec8285611afd565b6121b26020830184611afd565b606081016122078287611afd565b6122146020830186611afd565b8181036040830152612227818486611bbc565b9695505050505050565b6080810161223f8288611afd565b61224c6020830187611afd565b6122596040830186611c16565b818103606083015261226c818486611bbc565b979650505050505050565b604081016122858285611afd565b81810360208301526118098184611be8565b60208082528101610d088184611b0c565b60208082528101610d088184611b65565b60208101610d0b8284611bb3565b60208082528101610d088184611be8565b60208082528101610d0b81611c4e565b60208082528101610d0b81611c92565b60208082528101610d0b81611cd9565b60208082528101610d0b81611d27565b60208082528101610d0b81611d74565b60208082528101610d0b81611de5565b60208082528101610d0b81611e33565b60208082528101610d0b81611e80565b60208082528101610d0b81611ee9565b60208082528101610d0b81611f38565b60208082528101610d0b81611fb6565b60208082528101610d0b8161200d565b60208082528101610d0b8161206c565b60208082528101610d0b816120b8565b60208082528101610d0b81612107565b60208082528101610d0b81612158565b6040518181016001600160401b03811182821017156123f657600080fd5b604052919050565b60006001600160401b0382111561241457600080fd5b5060209081020190565b60006001600160401b0382111561243457600080fd5b506020601f91909101601f19160190565b60200190565b5190565b90815260200190565b6000610d0b82612472565b151590565b80610552816124ce565b6001600160a01b031690565b90565b6000610d0b82612468565b82818337506000910152565b60005b838110156124b357818101518382015260200161249b565b8381111561073b5750506000910152565b601f01601f191690565b60068110610d8857fe5b6124e181612458565b8114610d8857600080fd5b6124e181612463565b60068110610d8857600080fd5b6124e18161247e56fea264697066735822122039028b5af491b26024e0d524e00c89cbd9b50cf3473d360a21eb8ca9b122e0f464736f6c634300060c00330000000000000000000000007e6d3b1161df9c9c7527f68d651b297d2fdb820b

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638af6d89e116100a2578063a5c6e2b811610071578063a5c6e2b814610216578063bd8e959a14610236578063e8cf4d431461023e578063ee37ebcf14610251578063fa5d06e31461026457610116565b80638af6d89e146101d3578063961363d9146101f357806397c0ac87146101fb5780639c532bac1461020357610116565b806348f35209116100e957806348f352091461017f5780634ed28b3f1461019257806380d57063146101a5578063893d20e8146101b857806389cbe1d0146101c057610116565b80630442bad51461011b5780631bee801e1461013057806345d582e7146101435780634679034614610156575b600080fd5b61012e610129366004611900565b610277565b005b61012e61013e366004611933565b61043d565b61012e61015136600461182f565b610455565b6101696101643660046117eb565b610536565b60405161017691906121d0565b60405180910390f35b61012e61018d366004611869565b610557565b61012e6101a0366004611869565b6105ff565b61012e6101b3366004611a38565b6106e9565b610169610742565b61012e6101ce366004611a74565b6107da565b6101e66101e13660046117eb565b61085a565b6040516101769190612297565b6101e6610920565b6101696109b5565b61012e610211366004611966565b6109d9565b61022961022436600461182f565b610ce6565b60405161017691906122b9565b61012e610d11565b61022961024c3660046118d0565b610d8b565b61012e61025f366004611966565b610dd6565b6102296102723660046117eb565b610f96565b600061028285610536565b9050606061028f8661085a565b905060005b8151811015610434576102ba8282815181106102ac57fe5b602002602001015187610d8b565b6102c35761042c565b8181815181106102cf57fe5b60200260200101516001600160a01b0316635b8f1c5a88858989896040518663ffffffff1660e01b815260040161030a959493929190612231565b602060405180830381600087803b15801561032457600080fd5b505af1158015610338573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035c9190611a56565b82828151811061036857fe5b60200260200101516001600160a01b0316637998a1c46040518163ffffffff1660e01b815260040160006040518083038186803b1580156103a857600080fd5b505afa1580156103bc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526103e49190810190611aa9565b6040516020016103f491906121b9565b6040516020818303038152906040529061042a5760405162461bcd60e51b815260040161042191906122c7565b60405180910390fd5b505b600101610294565b50505050505050565b60405162461bcd60e51b815260040161042190612388565b80610461816004610d8b565b1580156104765750610474816005610d8b565b155b6104925760405162461bcd60e51b815260040161042190612368565b828261049e8282610ce6565b6104ba5760405162461bcd60e51b8152600401610421906123c8565b6104cc6104c686610536565b33610fa3565b6001600160a01b03851660009081526004602052604090206104ee9085611044565b50836001600160a01b0316856001600160a01b03167fd7b03d2e8be34a451c0a51c07755427856dd05d0343003f8a7ab0f1af52e96c560405160405180910390a35050505050565b6001600160a01b03808216600090815260208190526040902054165b919050565b82610563816004610d8b565b1580156105785750610576816005610d8b565b155b6105945760405162461bcd60e51b815260040161042190612368565b600061059f86610536565b90506105ab8133610fa3565b6105ec868686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061105992505050565b6105f7868287611180565b505050505050565b8261060b816004610d8b565b158015610620575061061e816005610d8b565b155b61063c5760405162461bcd60e51b815260040161042190612368565b84846106488282610ce6565b6106645760405162461bcd60e51b8152600401610421906123c8565b600061066f88610536565b905061067b8133610fa3565b6040516308945f1960e41b81526001600160a01b03881690638945f190906106ad908b9085908b908b906004016121f9565b600060405180830381600087803b1580156106c757600080fd5b505af11580156106db573d6000803e3d6000fd5b505050505050505050505050565b60006106f4336111dc565b9050811561073e5760606107073361085a565b905060005b815181101561073b57610733338484848151811061072657fe5b6020026020010151611180565b60010161070c565b50505b5050565b60007f0000000000000000000000007e6d3b1161df9c9c7527f68d651b297d2fdb820b6001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b15801561079d57600080fd5b505afa1580156107b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d59190611811565b905090565b6060806107e9838501856119a7565b91509150805182511461080e5760405162461bcd60e51b815260040161042190612348565b60005b82518110156108535761084b3384838151811061082a57fe5b602002602001015184848151811061083e57fe5b6020026020010151611059565b600101610811565b5050505050565b6001600160a01b038116600090815260046020526040902060609061087e90611382565b6001600160401b038111801561089357600080fd5b506040519080825280602002602001820160405280156108bd578160200160208202803683370190505b50905060005b815181101561091a576001600160a01b03831660009081526004602052604090206108ee908261138d565b8282815181106108fa57fe5b6001600160a01b03909216602092830291909101909101526001016108c3565b50919050565b606061092c6001611382565b6001600160401b038111801561094157600080fd5b5060405190808252806020026020018201604052801561096b578160200160208202803683370190505b50905060005b81518110156109b15761098560018261138d565b82828151811061099157fe5b6001600160a01b0390921660209283029190910190910152600101610971565b5090565b7f0000000000000000000000007e6d3b1161df9c9c7527f68d651b297d2fdb820b90565b6109e1610742565b6001600160a01b0316336001600160a01b031614610a115760405162461bcd60e51b815260040161042190612318565b80610a2e5760405162461bcd60e51b815260040161042190612338565b60005b81811015610ce157610a5d838383818110610a4857fe5b905060200201602081019061027291906117eb565b15610a7a5760405162461bcd60e51b815260040161042190612308565b610aa6838383818110610a8957fe5b9050602002016020810190610a9e91906117eb565b600190611399565b506000838383818110610ab557fe5b9050602002016020810190610aca91906117eb565b90506060816001600160a01b031663cbf54bb26040518163ffffffff1660e01b815260040160006040518083038186803b158015610b0757600080fd5b505afa158015610b1b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b439190810190611a04565b905060005b8151811015610beb57600160036000888888818110610b6357fe5b9050602002016020810190610b7891906117eb565b6001600160a01b03166001600160a01b031681526020019081526020016000206000848481518110610ba657fe5b60200260200101516005811115610bb957fe5b6005811115610bc457fe5b81526020810191909152604001600020805460ff1916911515919091179055600101610b48565b50816001600160a01b0316637998a1c46040518163ffffffff1660e01b815260040160006040518083038186803b158015610c2557600080fd5b505afa158015610c39573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c619190810190611aa9565b604051610c6e91906121a6565b6040518091039020858585818110610c8257fe5b9050602002016020810190610c9791906117eb565b6001600160a01b03167f7fc39bd4ad1acc50e51318d02e8590c304ae9c0060c220cc780ea18720745c5283604051610ccf91906122a8565b60405180910390a35050600101610a31565b505050565b6001600160a01b0382166000908152600460205260408120610d0890836113ae565b90505b92915050565b3360009081526020818152604080832080546001600160a01b031916905560049091528120610d3f90611382565b90505b8015610d8857336000908152600460205260409020610d7e90610d6990600019840161138d565b33600090815260046020526040902090611044565b5060001901610d42565b50565b6001600160a01b038216600090815260036020526040812081836005811115610db057fe5b6005811115610dbb57fe5b815260208101919091526040016000205460ff169392505050565b610dde610742565b6001600160a01b0316336001600160a01b031614610e0e5760405162461bcd60e51b815260040161042190612318565b80610e2b5760405162461bcd60e51b815260040161042190612358565b60005b81811015610ce157610e45838383818110610a4857fe5b610e615760405162461bcd60e51b8152600401610421906122f8565b610e8d838383818110610e7057fe5b9050602002016020810190610e8591906117eb565b600190611044565b50828282818110610e9a57fe5b9050602002016020810190610eaf91906117eb565b6001600160a01b0316637998a1c46040518163ffffffff1660e01b815260040160006040518083038186803b158015610ee757600080fd5b505afa158015610efb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f239190810190611aa9565b604051610f3091906121a6565b6040518091039020838383818110610f4457fe5b9050602002016020810190610f5991906117eb565b6001600160a01b03167f538f684b60a142c0b72b895be785c0aef10b373c6c5c4e8a7eb49baa244f64d360405160405180910390a3600101610e2e565b6000610d0b6001836113ae565b816001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b158015610fdc57600080fd5b505afa158015610ff0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110149190611811565b6001600160a01b0316816001600160a01b03161461073e5760405162461bcd60e51b815260040161042190612398565b6000610d08836001600160a01b0384166113c3565b6110638383610ce6565b156110805760405162461bcd60e51b8152600401610421906123a8565b61108982610f96565b6110a55760405162461bcd60e51b8152600401610421906123b8565b80511561110d57604051630f5f6b4f60e01b81526001600160a01b03831690630f5f6b4f906110da9086908590600401612277565b600060405180830381600087803b1580156110f457600080fd5b505af1158015611108573d6000803e3d6000fd5b505050505b6001600160a01b038316600090815260046020526040902061112f9083611399565b50816001600160a01b0316836001600160a01b03167faa4df4fe117c520783cfff01c11283496ff2999c77c2a9b800808251a9a0332a8360405161117391906122c7565b60405180910390a3505050565b604051630628da0b60e31b81526001600160a01b03821690633146d058906111ae90869086906004016121de565b600060405180830381600087803b1580156111c857600080fd5b505af1158015610434573d6000803e3d6000fd5b6001600160a01b03818116600090815260208190526040812054909116156112165760405162461bcd60e51b8152600401610421906122e8565b816001600160a01b031663c98091876040518163ffffffff1660e01b815260040160206040518083038186803b15801561124f57600080fd5b505afa158015611263573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112879190611811565b90506001600160a01b0381166112af5760405162461bcd60e51b815260040161042190612328565b806001600160a01b0316635a53e3486040518163ffffffff1660e01b815260040160206040518083038186803b1580156112e857600080fd5b505afa1580156112fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113209190611811565b6001600160a01b0316826001600160a01b0316146113505760405162461bcd60e51b815260040161042190612378565b6001600160a01b03918216600090815260208190526040902080546001600160a01b0319169282169290921790915590565b6000610d0b82611489565b6000610d08838361148d565b6000610d08836001600160a01b0384166114d2565b6000610d08836001600160a01b03841661151c565b6000818152600183016020526040812054801561147f57835460001980830191908101906000908790839081106113f657fe5b906000526020600020015490508087600001848154811061141357fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061144357fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610d0b565b6000915050610d0b565b5490565b815460009082106114b05760405162461bcd60e51b8152600401610421906122d8565b8260000182815481106114bf57fe5b9060005260206000200154905092915050565b60006114de838361151c565b61151457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610d0b565b506000610d0b565b60009081526001919091016020526040902054151590565b8035610d0b816124d8565b8051610d0b816124d8565b60008083601f84011261155c57600080fd5b5081356001600160401b0381111561157357600080fd5b60208301915083602082028301111561158b57600080fd5b9250929050565b600082601f8301126115a357600080fd5b81356115b66115b1826123fe565b6123d8565b915081818352602084019350602081019050838560208402820111156115db57600080fd5b60005b8381101561160757816115f18882611534565b84525060209283019291909101906001016115de565b5050505092915050565b600082601f83011261162257600080fd5b81356116306115b1826123fe565b81815260209384019390925082018360005b8381101561160757813586016116588882611735565b8452506020928301929190910190600101611642565b600082601f83011261167f57600080fd5b815161168d6115b1826123fe565b915081818352602084019350602081019050838560208402820111156116b257600080fd5b60005b8381101561160757816116c8888261178f565b84525060209283019291909101906001016116b5565b8035610d0b816124ec565b8051610d0b816124ec565b60008083601f84011261170657600080fd5b5081356001600160401b0381111561171d57600080fd5b60208301915083600182028301111561158b57600080fd5b600082601f83011261174657600080fd5b81356117546115b18261241e565b9150808252602083016020830185838301111561177057600080fd5b61177b83828461248c565b50505092915050565b8035610d0b816124f5565b8051610d0b816124f5565b600082601f8301126117ab57600080fd5b81516117b96115b18261241e565b915080825260208301602083018583830111156117d557600080fd5b61177b838284612498565b8035610d0b81612502565b6000602082840312156117fd57600080fd5b60006118098484611534565b949350505050565b60006020828403121561182357600080fd5b6000611809848461153f565b6000806040838503121561184257600080fd5b600061184e8585611534565b925050602061185f85828601611534565b9150509250929050565b6000806000806060858703121561187f57600080fd5b600061188b8787611534565b945050602061189c87828801611534565b93505060408501356001600160401b038111156118b857600080fd5b6118c4878288016116f4565b95989497509550505050565b600080604083850312156118e357600080fd5b60006118ef8585611534565b925050602061185f85828601611784565b6000806000806060858703121561191657600080fd5b60006119228787611534565b945050602061189c87828801611784565b6000806000806060858703121561194957600080fd5b60006119558787611534565b945050602061189c878288016117e0565b6000806020838503121561197957600080fd5b82356001600160401b0381111561198f57600080fd5b61199b8582860161154a565b92509250509250929050565b600080604083850312156119ba57600080fd5b82356001600160401b038111156119d057600080fd5b6119dc85828601611592565b92505060208301356001600160401b038111156119f857600080fd5b61185f85828601611611565b600060208284031215611a1657600080fd5b81516001600160401b03811115611a2c57600080fd5b6118098482850161166e565b600060208284031215611a4a57600080fd5b600061180984846116de565b600060208284031215611a6857600080fd5b600061180984846116e9565b60008060208385031215611a8757600080fd5b82356001600160401b03811115611a9d57600080fd5b61199b858286016116f4565b600060208284031215611abb57600080fd5b81516001600160401b03811115611ad157600080fd5b6118098482850161179a565b6000611ae98383611afd565b505060200190565b6000611ae98383611c16565b611b0681612458565b82525050565b6000611b178261244b565b611b21818561244f565b9350611b2c83612445565b8060005b83811015611b5a578151611b448882611add565b9750611b4f83612445565b925050600101611b30565b509495945050505050565b6000611b708261244b565b611b7a818561244f565b9350611b8583612445565b8060005b83811015611b5a578151611b9d8882611af1565b9750611ba883612445565b925050600101611b89565b611b0681612463565b6000611bc8838561244f565b9350611bd583858461248c565b611bde836124c4565b9093019392505050565b6000611bf38261244b565b611bfd818561244f565b9350611c0d818560208601612498565b611bde816124c4565b611b0681612481565b6000611c2a8261244b565b611c348185610552565b9350611c44818560208601612498565b9290920192915050565b6000611c5b60228361244f565b7f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e815261647360f01b602082015260400192915050565b6000611c9f60258361244f565b7f5f5f73657456616c6964617465645661756c7450726f78793a20416c726561648152641e481cd95d60da1b602082015260400192915050565b6000611ce6602c8361244f565b7f64657265676973746572506f6c69636965733a20706f6c696379206973206e6f81526b1d081c9959da5cdd195c995960a21b602082015260400192915050565b6000611d34602b8361244f565b7f7265676973746572506f6c69636965733a20706f6c69637920616c726561647981526a081c9959da5cdd195c995960aa1b602082015260400192915050565b6000611d8160498361244f565b7f6f6e6c7946756e644465706c6f7965724f776e65723a204f6e6c79207468652081527f46756e644465706c6f796572206f776e65722063616e2063616c6c207468697360208201526810333ab731ba34b7b760b91b604082015260600192915050565b6000611df2602c8361244f565b7f5f5f73657456616c6964617465645661756c7450726f78793a204d697373696e81526b67207661756c7450726f787960a01b602082015260400192915050565b6000611e40602b8361244f565b7f7265676973746572506f6c69636965733a205f706f6c69636965732063616e6e81526a6f7420626520656d70747960a81b602082015260400192915050565b6000611e8d60418361244f565b7f736574436f6e666967466f7246756e643a20706f6c696369657320616e64207381527f657474696e677344617461206172726179206c656e6774687320756e657175616020820152601b60fa1b604082015260600192915050565b6000611ef6602d8361244f565b7f64657265676973746572506f6c69636965733a205f706f6c696369657320636181526c6e6e6f7420626520656d70747960981b602082015260400192915050565b6000611f4560238361244f565b7f6f6e6c79427579536861726573486f6f6b733a20446973616c6c6f77656420688152626f6f6b60e81b602082015260400192915050565b6000611f8a601983610552565b7f52756c65206576616c756174656420746f2066616c73653a2000000000000000815260190192915050565b6000611fc360358361244f565b7f5f5f73657456616c6964617465645661756c7450726f78793a204e6f7420746881527432902b30bab63a283937bc3c9030b1b1b2b9b9b7b960591b602082015260400192915050565b600061201a60378361244f565b7f7265636569766543616c6c46726f6d436f6d7074726f6c6c65723a20556e696d81527f706c656d656e74656420666f7220457874656e73696f6e000000000000000000602082015260400192915050565b6000612079602a8361244f565b7f4f6e6c79207468652066756e64206f776e65722063616e2063616c6c207468698152693990333ab731ba34b7b760b11b602082015260400192915050565b60006120c5602d8361244f565b7f5f5f656e61626c65506f6c696379466f7246756e643a20706f6c69637920616c81526c1c9958591e48195b98589b1959609a1b602082015260400192915050565b6000612114602f8361244f565b7f5f5f656e61626c65506f6c696379466f7246756e643a20506f6c69637920697381526e081b9bdd081c9959da5cdd195c9959608a1b602082015260400192915050565b6000612165602c8361244f565b7f6f6e6c79456e61626c6564506f6c696379466f7246756e643a20506f6c69637981526b081b9bdd08195b98589b195960a21b602082015260400192915050565b60006121b28284611c1f565b9392505050565b60006121c482611f7d565b91506121b28284611c1f565b60208101610d0b8284611afd565b604081016121ec8285611afd565b6121b26020830184611afd565b606081016122078287611afd565b6122146020830186611afd565b8181036040830152612227818486611bbc565b9695505050505050565b6080810161223f8288611afd565b61224c6020830187611afd565b6122596040830186611c16565b818103606083015261226c818486611bbc565b979650505050505050565b604081016122858285611afd565b81810360208301526118098184611be8565b60208082528101610d088184611b0c565b60208082528101610d088184611b65565b60208101610d0b8284611bb3565b60208082528101610d088184611be8565b60208082528101610d0b81611c4e565b60208082528101610d0b81611c92565b60208082528101610d0b81611cd9565b60208082528101610d0b81611d27565b60208082528101610d0b81611d74565b60208082528101610d0b81611de5565b60208082528101610d0b81611e33565b60208082528101610d0b81611e80565b60208082528101610d0b81611ee9565b60208082528101610d0b81611f38565b60208082528101610d0b81611fb6565b60208082528101610d0b8161200d565b60208082528101610d0b8161206c565b60208082528101610d0b816120b8565b60208082528101610d0b81612107565b60208082528101610d0b81612158565b6040518181016001600160401b03811182821017156123f657600080fd5b604052919050565b60006001600160401b0382111561241457600080fd5b5060209081020190565b60006001600160401b0382111561243457600080fd5b506020601f91909101601f19160190565b60200190565b5190565b90815260200190565b6000610d0b82612472565b151590565b80610552816124ce565b6001600160a01b031690565b90565b6000610d0b82612468565b82818337506000910152565b60005b838110156124b357818101518382015260200161249b565b8381111561073b5750506000910152565b601f01601f191690565b60068110610d8857fe5b6124e181612458565b8114610d8857600080fd5b6124e181612463565b60068110610d8857600080fd5b6124e18161247e56fea264697066735822122039028b5af491b26024e0d524e00c89cbd9b50cf3473d360a21eb8ca9b122e0f464736f6c634300060c0033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000007e6d3b1161df9c9c7527f68d651b297d2fdb820b

-----Decoded View---------------
Arg [0] : _fundDeployer (address): 0x7e6d3b1161DF9c9c7527F68d651B297d2Fdb820B

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000007e6d3b1161df9c9c7527f68d651b297d2fdb820b


Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
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.