ETH Price: $3,393.97 (+1.39%)

Contract

0x5B67871C3a857dE81A1ca0f9F7945e5670D986Dc
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Transfer99748742020-04-30 15:57:451698 days ago1588262265IN
Set: Vault
0 ETH0.0004220
Set Time Lock Pe...76121802019-04-21 16:57:292073 days ago1555865849IN
Set: Vault
0 ETH0.000434420
Batch Transfer B...76116352019-04-21 14:52:182073 days ago1555858338IN
Set: Vault
0 ETH0.000110954
Batch Decrement ...76116252019-04-21 14:50:102073 days ago1555858210IN
Set: Vault
0 ETH0.000104924
Batch Increment ...76116212019-04-21 14:48:552073 days ago1555858135IN
Set: Vault
0 ETH0.000104924
Batch Withdraw T...76116172019-04-21 14:47:442073 days ago1555858064IN
Set: Vault
0 ETH0.000105274
Transfer Balance76115932019-04-21 14:44:042073 days ago1555857844IN
Set: Vault
0 ETH0.000106684
Decrement Token ...76115872019-04-21 14:43:082073 days ago1555857788IN
Set: Vault
0 ETH0.000100644
Increment Token ...76115642019-04-21 14:37:562073 days ago1555857476IN
Set: Vault
0 ETH0.000100724
Withdraw To76115622019-04-21 14:37:502073 days ago1555857470IN
Set: Vault
0 ETH0.00010094
Approve76115312019-04-21 14:29:382073 days ago1555856978IN
Set: Vault
0 ETH0.000092974
Remove Address76114672019-04-21 14:17:312073 days ago1555856251IN
Set: Vault
0 ETH0.000091824
Remove Authorize...76111992019-04-21 13:18:052073 days ago1555852685IN
Set: Vault
0 ETH0.000093164
Transfer Ownersh...76111682019-04-21 13:09:232073 days ago1555852163IN
Set: Vault
0 ETH0.000093594
Renounce Ownersh...76108142019-04-21 11:53:502073 days ago1555847630IN
Set: Vault
0 ETH0.000065553
Remove Authorize...76108032019-04-21 11:52:112073 days ago1555847531IN
Set: Vault
0 ETH0.000069873
Add Authorized A...76107892019-04-21 11:49:372073 days ago1555847377IN
Set: Vault
0 ETH0.000069933
Transfer Ownersh...75366912019-04-09 22:52:272085 days ago1554850347IN
Set: Vault
0 ETH0.000061292
Set Time Lock Pe...75366462019-04-09 22:41:512085 days ago1554849711IN
Set: Vault
0 ETH0.000084842
Add Authorized A...75366442019-04-09 22:41:282085 days ago1554849688IN
Set: Vault
0 ETH0.000172262

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Vault

Compiler Version
v0.5.7+commit.6da8b019

Optimization Enabled:
Yes with 200 runs

Other Settings:
byzantium EvmVersion

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2019-05-09
*/

// File: openzeppelin-solidity/contracts/math/SafeMath.sol

pragma solidity ^0.5.2;

/**
 * @title SafeMath
 * @dev Unsigned math operations with safety checks that revert on error
 */
library SafeMath {
    /**
     * @dev Multiplies two unsigned integers, reverts on overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b);

        return c;
    }

    /**
     * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Adds two unsigned integers, reverts on overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a);

        return c;
    }

    /**
     * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
     * reverts when dividing by zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0);
        return a % b;
    }
}

// File: openzeppelin-solidity/contracts/ownership/Ownable.sol

pragma solidity ^0.5.2;

/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev The Ownable constructor sets the original `owner` of the contract to the sender
     * account.
     */
    constructor () internal {
        _owner = msg.sender;
        emit OwnershipTransferred(address(0), _owner);
    }

    /**
     * @return the address of the owner.
     */
    function owner() public view returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(isOwner());
        _;
    }

    /**
     * @return true if `msg.sender` is the owner of the contract.
     */
    function isOwner() public view returns (bool) {
        return msg.sender == _owner;
    }

    /**
     * @dev Allows the current owner to relinquish control of the contract.
     * It will not be possible to call the functions with the `onlyOwner`
     * modifier anymore.
     * @notice Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Allows the current owner to transfer control of the contract to a newOwner.
     * @param newOwner The address to transfer ownership to.
     */
    function transferOwnership(address newOwner) public onlyOwner {
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers control of the contract to a newOwner.
     * @param newOwner The address to transfer ownership to.
     */
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0));
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

// File: contracts/lib/AddressArrayUtils.sol

// Pulled in from Cryptofin Solidity package in order to control Solidity compiler version
// https://github.com/cryptofinlabs/cryptofin-solidity/blob/master/contracts/array-utils/AddressArrayUtils.sol

pragma solidity 0.5.7;


library AddressArrayUtils {

    /**
     * Finds the index of the first occurrence of the given element.
     * @param A The input array to search
     * @param a The value to find
     * @return Returns (index and isIn) for the first occurrence starting from index 0
     */
    function indexOf(address[] memory A, address a) internal pure returns (uint256, bool) {
        uint256 length = A.length;
        for (uint256 i = 0; i < length; i++) {
            if (A[i] == a) {
                return (i, true);
            }
        }
        return (0, false);
    }

    /**
    * Returns true if the value is present in the list. Uses indexOf internally.
    * @param A The input array to search
    * @param a The value to find
    * @return Returns isIn for the first occurrence starting from index 0
    */
    function contains(address[] memory A, address a) internal pure returns (bool) {
        bool isIn;
        (, isIn) = indexOf(A, a);
        return isIn;
    }

    /// @return Returns index and isIn for the first occurrence starting from
    /// end
    function indexOfFromEnd(address[] memory A, address a) internal pure returns (uint256, bool) {
        uint256 length = A.length;
        for (uint256 i = length; i > 0; i--) {
            if (A[i - 1] == a) {
                return (i, true);
            }
        }
        return (0, false);
    }

    /**
     * Returns the combination of the two arrays
     * @param A The first array
     * @param B The second array
     * @return Returns A extended by B
     */
    function extend(address[] memory A, address[] memory B) internal pure returns (address[] memory) {
        uint256 aLength = A.length;
        uint256 bLength = B.length;
        address[] memory newAddresses = new address[](aLength + bLength);
        for (uint256 i = 0; i < aLength; i++) {
            newAddresses[i] = A[i];
        }
        for (uint256 j = 0; j < bLength; j++) {
            newAddresses[aLength + j] = B[j];
        }
        return newAddresses;
    }

    /**
     * Returns the array with a appended to A.
     * @param A The first array
     * @param a The value to append
     * @return Returns A appended by a
     */
    function append(address[] memory A, address a) internal pure returns (address[] memory) {
        address[] memory newAddresses = new address[](A.length + 1);
        for (uint256 i = 0; i < A.length; i++) {
            newAddresses[i] = A[i];
        }
        newAddresses[A.length] = a;
        return newAddresses;
    }

    /**
     * Returns the combination of two storage arrays.
     * @param A The first array
     * @param B The second array
     * @return Returns A appended by a
     */
    function sExtend(address[] storage A, address[] storage B) internal {
        uint256 length = B.length;
        for (uint256 i = 0; i < length; i++) {
            A.push(B[i]);
        }
    }

    /**
     * Returns the intersection of two arrays. Arrays are treated as collections, so duplicates are kept.
     * @param A The first array
     * @param B The second array
     * @return The intersection of the two arrays
     */
    function intersect(address[] memory A, address[] memory B) internal pure returns (address[] memory) {
        uint256 length = A.length;
        bool[] memory includeMap = new bool[](length);
        uint256 newLength = 0;
        for (uint256 i = 0; i < length; i++) {
            if (contains(B, A[i])) {
                includeMap[i] = true;
                newLength++;
            }
        }
        address[] memory newAddresses = new address[](newLength);
        uint256 j = 0;
        for (uint256 k = 0; k < length; k++) {
            if (includeMap[k]) {
                newAddresses[j] = A[k];
                j++;
            }
        }
        return newAddresses;
    }

    /**
     * Returns the union of the two arrays. Order is not guaranteed.
     * @param A The first array
     * @param B The second array
     * @return The union of the two arrays
     */
    function union(address[] memory A, address[] memory B) internal pure returns (address[] memory) {
        address[] memory leftDifference = difference(A, B);
        address[] memory rightDifference = difference(B, A);
        address[] memory intersection = intersect(A, B);
        return extend(leftDifference, extend(intersection, rightDifference));
    }

    /**
     * Alternate implementation
     * Assumes there are no duplicates
     */
    function unionB(address[] memory A, address[] memory B) internal pure returns (address[] memory) {
        bool[] memory includeMap = new bool[](A.length + B.length);
        uint256 count = 0;
        for (uint256 i = 0; i < A.length; i++) {
            includeMap[i] = true;
            count++;
        }
        for (uint256 j = 0; j < B.length; j++) {
            if (!contains(A, B[j])) {
                includeMap[A.length + j] = true;
                count++;
            }
        }
        address[] memory newAddresses = new address[](count);
        uint256 k = 0;
        for (uint256 m = 0; m < A.length; m++) {
            if (includeMap[m]) {
                newAddresses[k] = A[m];
                k++;
            }
        }
        for (uint256 n = 0; n < B.length; n++) {
            if (includeMap[A.length + n]) {
                newAddresses[k] = B[n];
                k++;
            }
        }
        return newAddresses;
    }

    /**
     * Computes the difference of two arrays. Assumes there are no duplicates.
     * @param A The first array
     * @param B The second array
     * @return The difference of the two arrays
     */
    function difference(address[] memory A, address[] memory B) internal pure returns (address[] memory) {
        uint256 length = A.length;
        bool[] memory includeMap = new bool[](length);
        uint256 count = 0;
        // First count the new length because can't push for in-memory arrays
        for (uint256 i = 0; i < length; i++) {
            address e = A[i];
            if (!contains(B, e)) {
                includeMap[i] = true;
                count++;
            }
        }
        address[] memory newAddresses = new address[](count);
        uint256 j = 0;
        for (uint256 k = 0; k < length; k++) {
            if (includeMap[k]) {
                newAddresses[j] = A[k];
                j++;
            }
        }
        return newAddresses;
    }

    /**
    * @dev Reverses storage array in place
    */
    function sReverse(address[] storage A) internal {
        address t;
        uint256 length = A.length;
        for (uint256 i = 0; i < length / 2; i++) {
            t = A[i];
            A[i] = A[A.length - i - 1];
            A[A.length - i - 1] = t;
        }
    }

    /**
    * Removes specified index from array
    * Resulting ordering is not guaranteed
    * @return Returns the new array and the removed entry
    */
    function pop(address[] memory A, uint256 index)
        internal
        pure
        returns (address[] memory, address)
    {
        uint256 length = A.length;
        address[] memory newAddresses = new address[](length - 1);
        for (uint256 i = 0; i < index; i++) {
            newAddresses[i] = A[i];
        }
        for (uint256 j = index + 1; j < length; j++) {
            newAddresses[j - 1] = A[j];
        }
        return (newAddresses, A[index]);
    }

    /**
     * @return Returns the new array
     */
    function remove(address[] memory A, address a)
        internal
        pure
        returns (address[] memory)
    {
        (uint256 index, bool isIn) = indexOf(A, a);
        if (!isIn) {
            revert();
        } else {
            (address[] memory _A,) = pop(A, index);
            return _A;
        }
    }

    function sPop(address[] storage A, uint256 index) internal returns (address) {
        uint256 length = A.length;
        if (index >= length) {
            revert("Error: index out of bounds");
        }
        address entry = A[index];
        for (uint256 i = index; i < length - 1; i++) {
            A[i] = A[i + 1];
        }
        A.length--;
        return entry;
    }

    /**
    * Deletes address at index and fills the spot with the last address.
    * Order is not preserved.
    * @return Returns the removed entry
    */
    function sPopCheap(address[] storage A, uint256 index) internal returns (address) {
        uint256 length = A.length;
        if (index >= length) {
            revert("Error: index out of bounds");
        }
        address entry = A[index];
        if (index != length - 1) {
            A[index] = A[length - 1];
            delete A[length - 1];
        }
        A.length--;
        return entry;
    }

    /**
     * Deletes address at index. Works by swapping it with the last address, then deleting.
     * Order is not preserved
     * @param A Storage array to remove from
     */
    function sRemoveCheap(address[] storage A, address a) internal {
        (uint256 index, bool isIn) = indexOf(A, a);
        if (!isIn) {
            revert("Error: entry not found");
        } else {
            sPopCheap(A, index);
            return;
        }
    }

    /**
     * Returns whether or not there's a duplicate. Runs in O(n^2).
     * @param A Array to search
     * @return Returns true if duplicate, false otherwise
     */
    function hasDuplicate(address[] memory A) internal pure returns (bool) {
        if (A.length == 0) {
            return false;
        }
        for (uint256 i = 0; i < A.length - 1; i++) {
            for (uint256 j = i + 1; j < A.length; j++) {
                if (A[i] == A[j]) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Returns whether the two arrays are equal.
     * @param A The first array
     * @param B The second array
     * @return True is the arrays are equal, false if not.
     */
    function isEqual(address[] memory A, address[] memory B) internal pure returns (bool) {
        if (A.length != B.length) {
            return false;
        }
        for (uint256 i = 0; i < A.length; i++) {
            if (A[i] != B[i]) {
                return false;
            }
        }
        return true;
    }

    /**
     * Returns the elements indexed at indexArray.
     * @param A The array to index
     * @param indexArray The array to use to index
     * @return Returns array containing elements indexed at indexArray
     */
    function argGet(address[] memory A, uint256[] memory indexArray)
        internal
        pure
        returns (address[] memory)
    {
        address[] memory array = new address[](indexArray.length);
        for (uint256 i = 0; i < indexArray.length; i++) {
            array[i] = A[indexArray[i]];
        }
        return array;
    }

}

// File: contracts/lib/TimeLockUpgrade.sol

/*
    Copyright 2018 Set Labs Inc.

    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

    http://www.apache.org/licenses/LICENSE-2.0

    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.
*/

pragma solidity 0.5.7;




/**
 * @title TimeLockUpgrade
 * @author Set Protocol
 *
 * The TimeLockUpgrade contract contains a modifier for handling minimum time period updates
 */
contract TimeLockUpgrade is
    Ownable
{
    using SafeMath for uint256;

    /* ============ State Variables ============ */

    // Timelock Upgrade Period in seconds
    uint256 public timeLockPeriod;

    // Mapping of upgradable units and initialized timelock
    mapping(bytes32 => uint256) public timeLockedUpgrades;

    /* ============ Events ============ */

    event UpgradeRegistered(
        bytes32 _upgradeHash,
        uint256 _timestamp
    );

    /* ============ Modifiers ============ */

    modifier timeLockUpgrade() {
        // If the time lock period is 0, then allow non-timebound upgrades.
        // This is useful for initialization of the protocol and for testing.
        if (timeLockPeriod == 0) {
            _;

            return;
        }

        // The upgrade hash is defined by the hash of the transaction call data,
        // which uniquely identifies the function as well as the passed in arguments.
        bytes32 upgradeHash = keccak256(
            abi.encodePacked(
                msg.data
            )
        );

        uint256 registrationTime = timeLockedUpgrades[upgradeHash];

        // If the upgrade hasn't been registered, register with the current time.
        if (registrationTime == 0) {
            timeLockedUpgrades[upgradeHash] = block.timestamp;

            emit UpgradeRegistered(
                upgradeHash,
                block.timestamp
            );

            return;
        }

        require(
            block.timestamp >= registrationTime.add(timeLockPeriod),
            "TimeLockUpgrade: Time lock period must have elapsed."
        );

        // Reset the timestamp to 0
        timeLockedUpgrades[upgradeHash] = 0;

        // Run the rest of the upgrades
        _;
    }

    /* ============ Function ============ */

    /**
     * Change timeLockPeriod period. Generally called after initially settings have been set up.
     *
     * @param  _timeLockPeriod   Time in seconds that upgrades need to be evaluated before execution
     */
    function setTimeLockPeriod(
        uint256 _timeLockPeriod
    )
        external
        onlyOwner
    {
        // Only allow setting of the timeLockPeriod if the period is greater than the existing
        require(
            _timeLockPeriod > timeLockPeriod,
            "TimeLockUpgrade: New period must be greater than existing"
        );

        timeLockPeriod = _timeLockPeriod;
    }
}

// File: contracts/lib/Authorizable.sol

/*
    Copyright 2018 Set Labs Inc.

    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

    http://www.apache.org/licenses/LICENSE-2.0

    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.
*/

pragma solidity 0.5.7;






/**
 * @title Authorizable
 * @author Set Protocol
 *
 * The Authorizable contract is an inherited contract that sets permissions on certain function calls
 * through the onlyAuthorized modifier. Permissions can be managed only by the Owner of the contract.
 */
contract Authorizable is
    Ownable,
    TimeLockUpgrade
{
    using SafeMath for uint256;
    using AddressArrayUtils for address[];

    /* ============ State Variables ============ */

    // Mapping of addresses to bool indicator of authorization
    mapping (address => bool) public authorized;

    // Array of authorized addresses
    address[] public authorities;

    /* ============ Modifiers ============ */

    // Only authorized addresses can invoke functions with this modifier.
    modifier onlyAuthorized {
        require(
            authorized[msg.sender],
            "Authorizable.onlyAuthorized: Sender not included in authorities"
        );
        _;
    }

    /* ============ Events ============ */

    // Event emitted when new address is authorized.
    event AddressAuthorized (
        address indexed authAddress,
        address authorizedBy
    );

    // Event emitted when address is deauthorized.
    event AuthorizedAddressRemoved (
        address indexed addressRemoved,
        address authorizedBy
    );

    /* ============ Setters ============ */

    /**
     * Add authorized address to contract. Can only be set by owner.
     *
     * @param  _authTarget   The address of the new authorized contract
     */

    function addAuthorizedAddress(address _authTarget)
        external
        onlyOwner
        timeLockUpgrade
    {
        // Require that address is not already authorized
        require(
            !authorized[_authTarget],
            "Authorizable.addAuthorizedAddress: Address already registered"
        );

        // Set address authority to true
        authorized[_authTarget] = true;

        // Add address to authorities array
        authorities.push(_authTarget);

        // Emit authorized address event
        emit AddressAuthorized(
            _authTarget,
            msg.sender
        );
    }

    /**
     * Remove authorized address from contract. Can only be set by owner.
     *
     * @param  _authTarget   The address to be de-permissioned
     */

    function removeAuthorizedAddress(address _authTarget)
        external
        onlyOwner
    {
        // Require address is authorized
        require(
            authorized[_authTarget],
            "Authorizable.removeAuthorizedAddress: Address not authorized"
        );

        // Delete address from authorized mapping
        authorized[_authTarget] = false;

        authorities = authorities.remove(_authTarget);

        // Emit AuthorizedAddressRemoved event.
        emit AuthorizedAddressRemoved(
            _authTarget,
            msg.sender
        );
    }

    /* ============ Getters ============ */

    /**
     * Get array of authorized addresses.
     *
     * @return address[]   Array of authorized addresses
     */
    function getAuthorizedAddresses()
        external
        view
        returns (address[] memory)
    {
        // Return array of authorized addresses
        return authorities;
    }
}

// File: contracts/lib/CommonMath.sol

/*
    Copyright 2018 Set Labs Inc.

    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

    http://www.apache.org/licenses/LICENSE-2.0

    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.
*/

pragma solidity 0.5.7;



library CommonMath {
    using SafeMath for uint256;

    /**
     * Calculates and returns the maximum value for a uint256
     *
     * @return  The maximum value for uint256
     */
    function maxUInt256()
        internal
        pure
        returns (uint256)
    {
        return 2 ** 256 - 1;
    }

    /**
    * @dev Performs the power on a specified value, reverts on overflow.
    */
    function safePower(
        uint256 a,
        uint256 pow
    )
        internal
        pure
        returns (uint256)
    {
        require(a > 0);

        uint256 result = 1;
        for (uint256 i = 0; i < pow; i++){
            uint256 previousResult = result;

            // Using safemath multiplication prevents overflows
            result = previousResult.mul(a);
        }

        return result;
    }

    /**
     * Checks for rounding errors and returns value of potential partial amounts of a principal
     *
     * @param  _principal       Number fractional amount is derived from
     * @param  _numerator       Numerator of fraction
     * @param  _denominator     Denominator of fraction
     * @return uint256          Fractional amount of principal calculated
     */
    function getPartialAmount(
        uint256 _principal,
        uint256 _numerator,
        uint256 _denominator
    )
        internal
        pure
        returns (uint256)
    {
        // Get remainder of partial amount (if 0 not a partial amount)
        uint256 remainder = mulmod(_principal, _numerator, _denominator);

        // Return if not a partial amount
        if (remainder == 0) {
            return _principal.mul(_numerator).div(_denominator);
        }

        // Calculate error percentage
        uint256 errPercentageTimes1000000 = remainder.mul(1000000).div(_numerator.mul(_principal));

        // Require error percentage is less than 0.1%.
        require(
            errPercentageTimes1000000 < 1000,
            "CommonMath.getPartialAmount: Rounding error exceeds bounds"
        );

        return _principal.mul(_numerator).div(_denominator);
    }

}

// File: contracts/lib/IERC20.sol

/*
    Copyright 2018 Set Labs Inc.

    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

    http://www.apache.org/licenses/LICENSE-2.0

    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.
*/

pragma solidity 0.5.7;


/**
 * @title IERC20
 * @author Set Protocol
 *
 * Interface for using ERC20 Tokens. This interface is needed to interact with tokens that are not
 * fully ERC20 compliant and return something other than true on successful transfers.
 */
interface IERC20 {
    function balanceOf(
        address _owner
    )
        external
        view
        returns (uint256);

    function allowance(
        address _owner,
        address _spender
    )
        external
        view
        returns (uint256);

    function transfer(
        address _to,
        uint256 _quantity
    )
        external;

    function transferFrom(
        address _from,
        address _to,
        uint256 _quantity
    )
        external;

    function approve(
        address _spender,
        uint256 _quantity
    )
        external
        returns (bool);
}

// File: contracts/lib/ERC20Wrapper.sol

/*
    Copyright 2018 Set Labs Inc.

    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

    http://www.apache.org/licenses/LICENSE-2.0

    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.
*/

pragma solidity 0.5.7;




/**
 * @title ERC20Wrapper
 * @author Set Protocol
 *
 * This library contains functions for interacting wtih ERC20 tokens, even those not fully compliant.
 * For all functions we will only accept tokens that return a null or true value, any other values will
 * cause the operation to revert.
 */
library ERC20Wrapper {

    // ============ Internal Functions ============

    /**
     * Check balance owner's balance of ERC20 token
     *
     * @param  _token          The address of the ERC20 token
     * @param  _owner          The owner who's balance is being checked
     * @return  uint256        The _owner's amount of tokens
     */
    function balanceOf(
        address _token,
        address _owner
    )
        external
        view
        returns (uint256)
    {
        return IERC20(_token).balanceOf(_owner);
    }

    /**
     * Checks spender's allowance to use token's on owner's behalf.
     *
     * @param  _token          The address of the ERC20 token
     * @param  _owner          The token owner address
     * @param  _spender        The address the allowance is being checked on
     * @return  uint256        The spender's allowance on behalf of owner
     */
    function allowance(
        address _token,
        address _owner,
        address _spender
    )
        internal
        view
        returns (uint256)
    {
        return IERC20(_token).allowance(_owner, _spender);
    }

    /**
     * Transfers tokens from an address. Handle's tokens that return true or null.
     * If other value returned, reverts.
     *
     * @param  _token          The address of the ERC20 token
     * @param  _to             The address to transfer to
     * @param  _quantity       The amount of tokens to transfer
     */
    function transfer(
        address _token,
        address _to,
        uint256 _quantity
    )
        external
    {
        IERC20(_token).transfer(_to, _quantity);

        // Check that transfer returns true or null
        require(
            checkSuccess(),
            "ERC20Wrapper.transfer: Bad return value"
        );
    }

    /**
     * Transfers tokens from an address (that has set allowance on the proxy).
     * Handle's tokens that return true or null. If other value returned, reverts.
     *
     * @param  _token          The address of the ERC20 token
     * @param  _from           The address to transfer from
     * @param  _to             The address to transfer to
     * @param  _quantity       The number of tokens to transfer
     */
    function transferFrom(
        address _token,
        address _from,
        address _to,
        uint256 _quantity
    )
        external
    {
        IERC20(_token).transferFrom(_from, _to, _quantity);

        // Check that transferFrom returns true or null
        require(
            checkSuccess(),
            "ERC20Wrapper.transferFrom: Bad return value"
        );
    }

    /**
     * Grants spender ability to spend on owner's behalf.
     * Handle's tokens that return true or null. If other value returned, reverts.
     *
     * @param  _token          The address of the ERC20 token
     * @param  _spender        The address to approve for transfer
     * @param  _quantity       The amount of tokens to approve spender for
     */
    function approve(
        address _token,
        address _spender,
        uint256 _quantity
    )
        internal
    {
        IERC20(_token).approve(_spender, _quantity);

        // Check that approve returns true or null
        require(
            checkSuccess(),
            "ERC20Wrapper.approve: Bad return value"
        );
    }

    /**
     * Ensure's the owner has granted enough allowance for system to
     * transfer tokens.
     *
     * @param  _token          The address of the ERC20 token
     * @param  _owner          The address of the token owner
     * @param  _spender        The address to grant/check allowance for
     * @param  _quantity       The amount to see if allowed for
     */
    function ensureAllowance(
        address _token,
        address _owner,
        address _spender,
        uint256 _quantity
    )
        internal
    {
        uint256 currentAllowance = allowance(_token, _owner, _spender);
        if (currentAllowance < _quantity) {
            approve(
                _token,
                _spender,
                CommonMath.maxUInt256()
            );
        }
    }

    // ============ Private Functions ============

    /**
     * Checks the return value of the previous function up to 32 bytes. Returns true if the previous
     * function returned 0 bytes or 1.
     */
    function checkSuccess(
    )
        private
        pure
        returns (bool)
    {
        // default to failure
        uint256 returnValue = 0;

        assembly {
            // check number of bytes returned from last function call
            switch returndatasize

            // no bytes returned: assume success
            case 0x0 {
                returnValue := 1
            }

            // 32 bytes returned
            case 0x20 {
                // copy 32 bytes into scratch space
                returndatacopy(0x0, 0x0, 0x20)

                // load those bytes into returnValue
                returnValue := mload(0x0)
            }

            // not sure what was returned: dont mark as success
            default { }
        }

        // check if returned value is one or nothing
        return returnValue == 1;
    }
}

// File: contracts/core/Vault.sol

/*
    Copyright 2018 Set Labs Inc.

    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

    http://www.apache.org/licenses/LICENSE-2.0

    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.
*/

pragma solidity 0.5.7;





/**
 * @title Vault
 * @author Set Protocol
 *
 * The vault contract is responsible for holding all funds and keeping track of the
 * fund state and which Sets own which funds.
 *
 */

contract Vault is
    Authorizable
{
    // Use SafeMath library for all uint256 arithmetic
    using SafeMath for uint256;

    /* ============ State Variables ============ */

    // Mapping of token address to map of owner or Set address to balance.
    // Example of mapping below:
    // +--------------+---------------------+--------+
    // | TokenAddress | Set OR User Address | Amount |
    // +--------------+---------------------+--------+
    // | TokenA       | User 0x123          |    500 |
    // |              | User 0xABC          |    300 |
    // |              | Set  0x456          |   1000 |
    // | TokenB       | User 0xDEF          |    100 |
    // |              | Set  0xSET          |    700 |
    // +--------------+---------------------+--------+
    mapping (address => mapping (address => uint256)) public balances;

    /* ============ External Functions ============ */

    /*
     * Withdraws user's unassociated tokens to user account. Can only be
     * called by authorized core contracts.
     *
     * @param  _token          The address of the ERC20 token
     * @param  _to             The address to transfer token to
     * @param  _quantity       The number of tokens to transfer
     */
    function withdrawTo(
        address _token,
        address _to,
        uint256 _quantity
    )
        public
        onlyAuthorized
    {
        if (_quantity > 0) {
            // Retrieve current balance of token for the vault
            uint256 existingVaultBalance = ERC20Wrapper.balanceOf(
                _token,
                address(this)
            );

            // Call specified ERC20 token contract to transfer tokens from Vault to user
            ERC20Wrapper.transfer(
                _token,
                _to,
                _quantity
            );

            // Verify transfer quantity is reflected in balance
            uint256 newVaultBalance = ERC20Wrapper.balanceOf(
                _token,
                address(this)
            );
            // Check to make sure current balances are as expected
            require(
                newVaultBalance == existingVaultBalance.sub(_quantity),
                "Vault.withdrawTo: Invalid post withdraw balance"
            );
        }
    }

    /*
     * Increment quantity owned of a token for a given address. Can
     * only be called by authorized core contracts.
     *
     * @param  _token           The address of the ERC20 token
     * @param  _owner           The address of the token owner
     * @param  _quantity        The number of tokens to attribute to owner
     */
    function incrementTokenOwner(
        address _token,
        address _owner,
        uint256 _quantity
    )
        public
        onlyAuthorized
    {
        if (_quantity > 0) {
            // Increment balances state variable adding _quantity to user's token amount
            balances[_token][_owner] = balances[_token][_owner].add(_quantity);
        }
    }

    /*
     * Decrement quantity owned of a token for a given address. Can only
     * be called by authorized core contracts.
     *
     * @param  _token           The address of the ERC20 token
     * @param  _owner           The address of the token owner
     * @param  _quantity        The number of tokens to deattribute to owner
     */
    function decrementTokenOwner(
        address _token,
        address _owner,
        uint256 _quantity
    )
        public
        onlyAuthorized
    {
        // Require that user has enough unassociated tokens to withdraw tokens or issue Set
        require(
            balances[_token][_owner] >= _quantity,
            "Vault.decrementTokenOwner: Insufficient token balance"
        );

        if (_quantity > 0) {
            // Decrement balances state variable subtracting _quantity to user's token amount
            balances[_token][_owner] = balances[_token][_owner].sub(_quantity);
        }
    }

    /**
     * Transfers tokens associated with one account to another account in the vault
     *
     * @param  _token          Address of token being transferred
     * @param  _from           Address token being transferred from
     * @param  _to             Address token being transferred to
     * @param  _quantity       Amount of tokens being transferred
     */

    function transferBalance(
        address _token,
        address _from,
        address _to,
        uint256 _quantity
    )
        public
        onlyAuthorized
    {
        if (_quantity > 0) {
            // Require that user has enough unassociated tokens to withdraw tokens or issue Set
            require(
                balances[_token][_from] >= _quantity,
                "Vault.transferBalance: Insufficient token balance"
            );

            // Decrement balances state variable subtracting _quantity to user's token amount
            balances[_token][_from] = balances[_token][_from].sub(_quantity);

            // Increment balances state variable adding _quantity to user's token amount
            balances[_token][_to] = balances[_token][_to].add(_quantity);
        }
    }

    /*
     * Withdraws user's unassociated tokens to user account. Can only be
     * called by authorized core contracts.
     *
     * @param  _tokens          The addresses of the ERC20 tokens
     * @param  _to              The address of the recipient
     * @param  _quantities      The numbers of tokens to attribute to owner
     */
    function batchWithdrawTo(
        address[] calldata _tokens,
        address _to,
        uint256[] calldata _quantities
    )
        external
        onlyAuthorized
    {
        // Storing token count to local variable to save on invocation
        uint256 tokenCount = _tokens.length;

        // Confirm and empty _tokens array is not passed
        require(
            tokenCount > 0,
            "Vault.batchWithdrawTo: Tokens must not be empty"
        );

        // Confirm there is one quantity for every token address
        require(
            tokenCount == _quantities.length,
            "Vault.batchWithdrawTo: Tokens and quantities lengths mismatch"
        );

        for (uint256 i = 0; i < tokenCount; i++) {
            withdrawTo(
                _tokens[i],
                _to,
                _quantities[i]
            );
        }
    }

    /*
     * Increment quantites owned of a collection of tokens for a given address. Can
     * only be called by authorized core contracts.
     *
     * @param  _tokens          The addresses of the ERC20 tokens
     * @param  _owner           The address of the token owner
     * @param  _quantities      The numbers of tokens to attribute to owner
     */
    function batchIncrementTokenOwner(
        address[] calldata _tokens,
        address _owner,
        uint256[] calldata _quantities
    )
        external
        onlyAuthorized
    {
        // Storing token count to local variable to save on invocation
        uint256 tokenCount = _tokens.length;

        // Confirm and empty _tokens array is not passed
        require(
            tokenCount > 0,
            "Vault.batchIncrementTokenOwner: Tokens must not be empty"
        );

        // Confirm there is one quantity for every token address
        require(
            tokenCount == _quantities.length,
            "Vault.batchIncrementTokenOwner: Tokens and quantities lengths mismatch"
        );

        for (uint256 i = 0; i < tokenCount; i++) {
            incrementTokenOwner(
                _tokens[i],
                _owner,
                _quantities[i]
            );
        }
    }

    /*
     * Decrements quantites owned of a collection of tokens for a given address. Can
     * only be called by authorized core contracts.
     *
     * @param  _tokens          The addresses of the ERC20 tokens
     * @param  _owner           The address of the token owner
     * @param  _quantities      The numbers of tokens to attribute to owner
     */
    function batchDecrementTokenOwner(
        address[] calldata _tokens,
        address _owner,
        uint256[] calldata _quantities
    )
        external
        onlyAuthorized
    {
        // Storing token count to local variable to save on invocation
        uint256 tokenCount = _tokens.length;

        // Confirm and empty _tokens array is not passed
        require(
            tokenCount > 0,
            "Vault.batchDecrementTokenOwner: Tokens must not be empty"
        );

        // Confirm there is one quantity for every token address
        require(
            tokenCount == _quantities.length,
            "Vault.batchDecrementTokenOwner: Tokens and quantities lengths mismatch"
        );

        for (uint256 i = 0; i < tokenCount; i++) {
            decrementTokenOwner(
                _tokens[i],
                _owner,
                _quantities[i]
            );
        }
    }

    /**
     * Transfers tokens associated with one account to another account in the vault
     *
     * @param  _tokens           Addresses of tokens being transferred
     * @param  _from             Address tokens being transferred from
     * @param  _to               Address tokens being transferred to
     * @param  _quantities       Amounts of tokens being transferred
     */
    function batchTransferBalance(
        address[] calldata _tokens,
        address _from,
        address _to,
        uint256[] calldata _quantities
    )
        external
        onlyAuthorized
    {
        // Storing token count to local variable to save on invocation
        uint256 tokenCount = _tokens.length;

        // Confirm and empty _tokens array is not passed
        require(
            tokenCount > 0,
            "Vault.batchTransferBalance: Tokens must not be empty"
        );

        // Confirm there is one quantity for every token address
        require(
            tokenCount == _quantities.length,
            "Vault.batchTransferBalance: Tokens and quantities lengths mismatch"
        );

        for (uint256 i = 0; i < tokenCount; i++) {
            transferBalance(
                _tokens[i],
                _from,
                _to,
                _quantities[i]
            );
        }
    }

    /*
     * Get balance of particular contract for owner.
     *
     * @param  _token           The address of the ERC20 token
     * @param  _owner           The address of the token owner
     */
    function getOwnerBalance(
        address _token,
        address _owner
    )
        external
        view
        returns (uint256)
    {
        // Return owners token balance
        return balances[_token][_owner];
    }
}

Contract Security Audit

Contract ABI

[{"constant":false,"inputs":[{"name":"_tokens","type":"address[]"},{"name":"_owner","type":"address"},{"name":"_quantities","type":"uint256[]"}],"name":"batchIncrementTokenOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"timeLockedUpgrades","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_token","type":"address"},{"name":"_owner","type":"address"}],"name":"getOwnerBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_tokens","type":"address[]"},{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_quantities","type":"uint256[]"}],"name":"batchTransferBalance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tokens","type":"address[]"},{"name":"_to","type":"address"},{"name":"_quantities","type":"uint256[]"}],"name":"batchWithdrawTo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tokens","type":"address[]"},{"name":"_owner","type":"address"},{"name":"_quantities","type":"uint256[]"}],"name":"batchDecrementTokenOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_authTarget","type":"address"}],"name":"addAuthorizedAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"authorities","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_authTarget","type":"address"}],"name":"removeAuthorizedAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"timeLockPeriod","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"},{"name":"_owner","type":"address"},{"name":"_quantity","type":"uint256"}],"name":"decrementTokenOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_timeLockPeriod","type":"uint256"}],"name":"setTimeLockPeriod","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"},{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_quantity","type":"uint256"}],"name":"transferBalance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"authorized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"},{"name":"_owner","type":"address"},{"name":"_quantity","type":"uint256"}],"name":"incrementTokenOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"balances","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"},{"name":"_to","type":"address"},{"name":"_quantity","type":"uint256"}],"name":"withdrawTo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getAuthorizedAddresses","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"authAddress","type":"address"},{"indexed":false,"name":"authorizedBy","type":"address"}],"name":"AddressAuthorized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"addressRemoved","type":"address"},{"indexed":false,"name":"authorizedBy","type":"address"}],"name":"AuthorizedAddressRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_upgradeHash","type":"bytes32"},{"indexed":false,"name":"_timestamp","type":"uint256"}],"name":"UpgradeRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]

6080604081905260008054600160a060020a0319163317808255600160a060020a0316917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3611edb806100576000396000f3fe608060405234801561001057600080fd5b506004361061015f576000357c01000000000000000000000000000000000000000000000000000000009004806380ddda30116100d5578063b918161111610099578063b918161114610653578063bada572614610679578063c23f001f146106af578063c3b35a7e146106dd578063d39de6e914610713578063f2fde38b1461076b5761015f565b806380ddda30146105a05780638da5cb5b146105d65780638f32d59b146105de5780639303b16f146105fa578063b19ad577146106175761015f565b80633911477c116101275780633911477c1461043c57806342f1181e1461050b578063494503d414610531578063707129391461056a578063715018a61461059057806378446bc1146105985761015f565b806312a3bbe3146101645780631766486d146102355780631f98ade31461026457806320153c38146102925780632321af6a1461036d575b600080fd5b6102336004803603606081101561017a57600080fd5b81019060208101813564010000000081111561019557600080fd5b8201836020820111156101a757600080fd5b803590602001918460208302840111640100000000831117156101c957600080fd5b91939092600160a060020a03833516926040810190602001356401000000008111156101f457600080fd5b82018360208201111561020657600080fd5b8035906020019184602083028401116401000000008311171561022857600080fd5b509092509050610791565b005b6102526004803603602081101561024b57600080fd5b50356108b7565b60408051918252519081900360200190f35b6102526004803603604081101561027a57600080fd5b50600160a060020a03813581169160200135166108c9565b610233600480360360808110156102a857600080fd5b8101906020810181356401000000008111156102c357600080fd5b8201836020820111156102d557600080fd5b803590602001918460208302840111640100000000831117156102f757600080fd5b91939092600160a060020a038335811693602081013590911692919060608101906040013564010000000081111561032e57600080fd5b82018360208201111561034057600080fd5b8035906020019184602083028401116401000000008311171561036257600080fd5b5090925090506108f6565b6102336004803603606081101561038357600080fd5b81019060208101813564010000000081111561039e57600080fd5b8201836020820111156103b057600080fd5b803590602001918460208302840111640100000000831117156103d257600080fd5b91939092600160a060020a03833516926040810190602001356401000000008111156103fd57600080fd5b82018360208201111561040f57600080fd5b8035906020019184602083028401116401000000008311171561043157600080fd5b509092509050610a1e565b6102336004803603606081101561045257600080fd5b81019060208101813564010000000081111561046d57600080fd5b82018360208201111561047f57600080fd5b803590602001918460208302840111640100000000831117156104a157600080fd5b91939092600160a060020a03833516926040810190602001356401000000008111156104cc57600080fd5b8201836020820111156104de57600080fd5b8035906020019184602083028401116401000000008311171561050057600080fd5b509092509050610b3b565b6102336004803603602081101561052157600080fd5b5035600160a060020a0316610c58565b61054e6004803603602081101561054757600080fd5b5035610f82565b60408051600160a060020a039092168252519081900360200190f35b6102336004803603602081101561058057600080fd5b5035600160a060020a0316610fa9565b6102336110f8565b610252611160565b610233600480360360608110156105b657600080fd5b50600160a060020a03813581169160208101359091169060400135611166565b61054e611286565b6105e6611296565b604080519115158252519081900360200190f35b6102336004803603602081101561061057600080fd5b50356112a7565b6102336004803603608081101561062d57600080fd5b50600160a060020a03813581169160208101358216916040820135169060600135611300565b6105e66004803603602081101561066957600080fd5b5035600160a060020a031661145d565b6102336004803603606081101561068f57600080fd5b50600160a060020a03813581169160208101359091169060400135611472565b610252600480360360408110156106c557600080fd5b50600160a060020a03813581169160200135166114ff565b610233600480360360608110156106f357600080fd5b50600160a060020a0381358116916020810135909116906040013561151c565b61071b6117bc565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561075757818101518382015260200161073f565b505050509050019250505060405180910390f35b6102336004803603602081101561078157600080fd5b5035600160a060020a031661181e565b3360009081526003602052604090205460ff166107e25760405160e560020a62461bcd02815260040180806020018281038252603f815260200180611c93603f913960400191505060405180910390fd5b83806108225760405160e560020a62461bcd028152600401808060200182810382526038815260200180611b5e6038913960400191505060405180910390fd5b8082146108635760405160e560020a62461bcd028152600401808060200182810382526046815260200180611c106046913960600191505060405180910390fd5b60005b818110156108ae576108a687878381811061087d57fe5b90506020020135600160a060020a03168686868581811061089a57fe5b90506020020135611472565b600101610866565b50505050505050565b60026020526000908152604090205481565b600160a060020a038083166000908152600560209081526040808320938516835292905220545b92915050565b3360009081526003602052604090205460ff166109475760405160e560020a62461bcd02815260040180806020018281038252603f815260200180611c93603f913960400191505060405180910390fd5b84806109875760405160e560020a62461bcd028152600401808060200182810382526034815260200180611cd26034913960400191505060405180910390fd5b8082146109c85760405160e560020a62461bcd028152600401808060200182810382526042815260200180611bce6042913960600191505060405180910390fd5b60005b81811015610a1457610a0c8888838181106109e257fe5b90506020020135600160a060020a03168787878786818110610a0057fe5b90506020020135611300565b6001016109cb565b5050505050505050565b3360009081526003602052604090205460ff16610a6f5760405160e560020a62461bcd02815260040180806020018281038252603f815260200180611c93603f913960400191505060405180910390fd5b8380610aaf5760405160e560020a62461bcd02815260040180806020018281038252602f815260200180611e81602f913960400191505060405180910390fd5b808214610af05760405160e560020a62461bcd02815260040180806020018281038252603d815260200180611d3b603d913960400191505060405180910390fd5b60005b818110156108ae57610b33878783818110610b0a57fe5b90506020020135600160a060020a031686868685818110610b2757fe5b9050602002013561151c565b600101610af3565b3360009081526003602052604090205460ff16610b8c5760405160e560020a62461bcd02815260040180806020018281038252603f815260200180611c93603f913960400191505060405180910390fd5b8380610bcc5760405160e560020a62461bcd028152600401808060200182810382526038815260200180611b966038913960400191505060405180910390fd5b808214610c0d5760405160e560020a62461bcd028152600401808060200182810382526046815260200180611b186046913960600191505060405180910390fd5b60005b818110156108ae57610c50878783818110610c2757fe5b90506020020135600160a060020a031686868685818110610c4457fe5b90506020020135611166565b600101610c10565b610c60611296565b610c6957600080fd5b600154610d7757600160a060020a03811660009081526003602052604090205460ff1615610ccb5760405160e560020a62461bcd02815260040180806020018281038252603d815260200180611c56603d913960400191505060405180910390fd5b600160a060020a0381166000818152600360209081526040808320805460ff191660019081179091556004805491820181559093527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b909201805473ffffffffffffffffffffffffffffffffffffffff191684179055815133815291517f8918da6429714f0e9c40ae7f270773e27fc8caf7a256e19807f859563b7514de9281900390910190a2610f7f565b60008036604051602001808383808284376040805191909301818103601f1901825283528051602091820120600081815260029092529290205491955090935050508115159050610e1657600082815260026020908152604091829020429081905582518581529182015281517f0e0905d1a972d476e353bdcc3e06b19a71709054c8ba01eccb7e0691eca6d374929181900390910190a15050610f7f565b600154610e2a90829063ffffffff61183816565b421015610e6b5760405160e560020a62461bcd028152600401808060200182810382526034815260200180611e146034913960400191505060405180910390fd5b6000828152600260209081526040808320839055600160a060020a0386168352600390915290205460ff1615610ed55760405160e560020a62461bcd02815260040180806020018281038252603d815260200180611c56603d913960400191505060405180910390fd5b600160a060020a0383166000818152600360209081526040808320805460ff191660019081179091556004805491820181559093527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b909201805473ffffffffffffffffffffffffffffffffffffffff191684179055815133815291517f8918da6429714f0e9c40ae7f270773e27fc8caf7a256e19807f859563b7514de9281900390910190a250505b50565b60048181548110610f8f57fe5b600091825260209091200154600160a060020a0316905081565b610fb1611296565b610fba57600080fd5b600160a060020a03811660009081526003602052604090205460ff166110145760405160e560020a62461bcd02815260040180806020018281038252603c815260200180611d78603c913960400191505060405180910390fd5b600160a060020a038116600090815260036020908152604091829020805460ff19169055600480548351818402810184019094528084526110a19385939092919083018282801561108e57602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311611070575b505050505061185190919063ffffffff16565b80516110b591600491602090910190611a74565b50604080513381529051600160a060020a038316917f1f32c1b084e2de0713b8fb16bd46bb9df710a3dbeae2f3ca93af46e016dcc6b0919081900360200190a250565b611100611296565b61110957600080fd5b60008054604051600160a060020a03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a36000805473ffffffffffffffffffffffffffffffffffffffff19169055565b60015481565b3360009081526003602052604090205460ff166111b75760405160e560020a62461bcd02815260040180806020018281038252603f815260200180611c93603f913960400191505060405180910390fd5b600160a060020a0380841660009081526005602090815260408083209386168352929052205481111561121e5760405160e560020a62461bcd028152600401808060200182810382526035815260200180611d066035913960400191505060405180910390fd5b801561128157600160a060020a0380841660009081526005602090815260408083209386168352929052205461125a908263ffffffff61188616565b600160a060020a038085166000908152600560209081526040808320938716835292905220555b505050565b600054600160a060020a03165b90565b600054600160a060020a0316331490565b6112af611296565b6112b857600080fd5b60015481116112fb5760405160e560020a62461bcd028152600401808060200182810382526039815260200180611e486039913960400191505060405180910390fd5b600155565b3360009081526003602052604090205460ff166113515760405160e560020a62461bcd02815260040180806020018281038252603f815260200180611c93603f913960400191505060405180910390fd5b801561145757600160a060020a038085166000908152600560209081526040808320938716835292905220548111156113be5760405160e560020a62461bcd028152600401808060200182810382526031815260200180611de36031913960400191505060405180910390fd5b600160a060020a038085166000908152600560209081526040808320938716835292905220546113f4908263ffffffff61188616565b600160a060020a038581166000908152600560209081526040808320888516845290915280822093909355908416815220546114309082611838565b600160a060020a038086166000908152600560209081526040808320938716835292905220555b50505050565b60036020526000908152604090205460ff1681565b3360009081526003602052604090205460ff166114c35760405160e560020a62461bcd02815260040180806020018281038252603f815260200180611c93603f913960400191505060405180910390fd5b801561128157600160a060020a0380841660009081526005602090815260408083209386168352929052205461125a908263ffffffff61183816565b600560209081526000928352604080842090915290825290205481565b3360009081526003602052604090205460ff1661156d5760405160e560020a62461bcd02815260040180806020018281038252603f815260200180611c93603f913960400191505060405180910390fd5b801561128157604080517ff7888aec000000000000000000000000000000000000000000000000000000008152600160a060020a0385166004820152306024820152905160009173eadada7c6943c223c0d4bea475a6dacc7368f8d69163f7888aec91604480820192602092909190829003018186803b1580156115f057600080fd5b505af4158015611604573d6000803e3d6000fd5b505050506040513d602081101561161a57600080fd5b5051604080517fbeabacc8000000000000000000000000000000000000000000000000000000008152600160a060020a0380881660048301528616602482015260448101859052905191925073eadada7c6943c223c0d4bea475a6dacc7368f8d69163beabacc891606480820192600092909190829003018186803b1580156116a257600080fd5b505af41580156116b6573d6000803e3d6000fd5b5050604080517ff7888aec000000000000000000000000000000000000000000000000000000008152600160a060020a038816600482015230602482015290516000935073eadada7c6943c223c0d4bea475a6dacc7368f8d6925063f7888aec91604480820192602092909190829003018186803b15801561173757600080fd5b505af415801561174b573d6000803e3d6000fd5b505050506040513d602081101561176157600080fd5b50519050611775828463ffffffff61188616565b81146117b55760405160e560020a62461bcd02815260040180806020018281038252602f815260200180611db4602f913960400191505060405180910390fd5b5050505050565b6060600480548060200260200160405190810160405280929190818152602001828054801561181457602002820191906000526020600020905b8154600160a060020a031681526001909101906020018083116117f6575b5050505050905090565b611826611296565b61182f57600080fd5b610f7f8161189b565b60008282018381101561184a57600080fd5b9392505050565b60606000806118608585611916565b915091508061186e57600080fd5b606061187a868461197a565b5093506108f092505050565b60008282111561189557600080fd5b50900390565b600160a060020a0381166118ae57600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b81516000908190815b818110156119695784600160a060020a031686828151811061193d57fe5b6020026020010151600160a060020a03161415611961579250600191506119739050565b60010161191f565b5060009250829150505b9250929050565b6060600080845190506060600182036040519080825280602002602001820160405280156119b2578160200160208202803883390190505b50905060005b85811015611a00578681815181106119cc57fe5b60200260200101518282815181106119e057fe5b600160a060020a03909216602092830291909101909101526001016119b8565b50600185015b82811015611a5157868181518110611a1a57fe5b6020026020010151826001830381518110611a3157fe5b600160a060020a0390921660209283029190910190910152600101611a06565b5080868681518110611a5f57fe5b60200260200101519350935050509250929050565b828054828255906000526020600020908101928215611ad6579160200282015b82811115611ad6578251825473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03909116178255602090920191600190910190611a94565b50611ae2929150611ae6565b5090565b61129391905b80821115611ae257805473ffffffffffffffffffffffffffffffffffffffff19168155600101611aec56fe5661756c742e626174636844656372656d656e74546f6b656e4f776e65723a20546f6b656e7320616e64207175616e746974696573206c656e67746873206d69736d617463685661756c742e6261746368496e6372656d656e74546f6b656e4f776e65723a20546f6b656e73206d757374206e6f7420626520656d7074795661756c742e626174636844656372656d656e74546f6b656e4f776e65723a20546f6b656e73206d757374206e6f7420626520656d7074795661756c742e62617463685472616e7366657242616c616e63653a20546f6b656e7320616e64207175616e746974696573206c656e67746873206d69736d617463685661756c742e6261746368496e6372656d656e74546f6b656e4f776e65723a20546f6b656e7320616e64207175616e746974696573206c656e67746873206d69736d61746368417574686f72697a61626c652e616464417574686f72697a6564416464726573733a204164647265737320616c72656164792072656769737465726564417574686f72697a61626c652e6f6e6c79417574686f72697a65643a2053656e646572206e6f7420696e636c7564656420696e20617574686f7269746965735661756c742e62617463685472616e7366657242616c616e63653a20546f6b656e73206d757374206e6f7420626520656d7074795661756c742e64656372656d656e74546f6b656e4f776e65723a20496e73756666696369656e7420746f6b656e2062616c616e63655661756c742e62617463685769746864726177546f3a20546f6b656e7320616e64207175616e746974696573206c656e67746873206d69736d61746368417574686f72697a61626c652e72656d6f7665417574686f72697a6564416464726573733a2041646472657373206e6f7420617574686f72697a65645661756c742e7769746864726177546f3a20496e76616c696420706f73742077697468647261772062616c616e63655661756c742e7472616e7366657242616c616e63653a20496e73756666696369656e7420746f6b656e2062616c616e636554696d654c6f636b557067726164653a2054696d65206c6f636b20706572696f64206d757374206861766520656c61707365642e54696d654c6f636b557067726164653a204e657720706572696f64206d7573742062652067726561746572207468616e206578697374696e675661756c742e62617463685769746864726177546f3a20546f6b656e73206d757374206e6f7420626520656d707479a165627a7a72305820f480fd92e3c5500732696bb72ac4c783538dc9cf7a7880b833efd8beea04f8170029

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061015f576000357c01000000000000000000000000000000000000000000000000000000009004806380ddda30116100d5578063b918161111610099578063b918161114610653578063bada572614610679578063c23f001f146106af578063c3b35a7e146106dd578063d39de6e914610713578063f2fde38b1461076b5761015f565b806380ddda30146105a05780638da5cb5b146105d65780638f32d59b146105de5780639303b16f146105fa578063b19ad577146106175761015f565b80633911477c116101275780633911477c1461043c57806342f1181e1461050b578063494503d414610531578063707129391461056a578063715018a61461059057806378446bc1146105985761015f565b806312a3bbe3146101645780631766486d146102355780631f98ade31461026457806320153c38146102925780632321af6a1461036d575b600080fd5b6102336004803603606081101561017a57600080fd5b81019060208101813564010000000081111561019557600080fd5b8201836020820111156101a757600080fd5b803590602001918460208302840111640100000000831117156101c957600080fd5b91939092600160a060020a03833516926040810190602001356401000000008111156101f457600080fd5b82018360208201111561020657600080fd5b8035906020019184602083028401116401000000008311171561022857600080fd5b509092509050610791565b005b6102526004803603602081101561024b57600080fd5b50356108b7565b60408051918252519081900360200190f35b6102526004803603604081101561027a57600080fd5b50600160a060020a03813581169160200135166108c9565b610233600480360360808110156102a857600080fd5b8101906020810181356401000000008111156102c357600080fd5b8201836020820111156102d557600080fd5b803590602001918460208302840111640100000000831117156102f757600080fd5b91939092600160a060020a038335811693602081013590911692919060608101906040013564010000000081111561032e57600080fd5b82018360208201111561034057600080fd5b8035906020019184602083028401116401000000008311171561036257600080fd5b5090925090506108f6565b6102336004803603606081101561038357600080fd5b81019060208101813564010000000081111561039e57600080fd5b8201836020820111156103b057600080fd5b803590602001918460208302840111640100000000831117156103d257600080fd5b91939092600160a060020a03833516926040810190602001356401000000008111156103fd57600080fd5b82018360208201111561040f57600080fd5b8035906020019184602083028401116401000000008311171561043157600080fd5b509092509050610a1e565b6102336004803603606081101561045257600080fd5b81019060208101813564010000000081111561046d57600080fd5b82018360208201111561047f57600080fd5b803590602001918460208302840111640100000000831117156104a157600080fd5b91939092600160a060020a03833516926040810190602001356401000000008111156104cc57600080fd5b8201836020820111156104de57600080fd5b8035906020019184602083028401116401000000008311171561050057600080fd5b509092509050610b3b565b6102336004803603602081101561052157600080fd5b5035600160a060020a0316610c58565b61054e6004803603602081101561054757600080fd5b5035610f82565b60408051600160a060020a039092168252519081900360200190f35b6102336004803603602081101561058057600080fd5b5035600160a060020a0316610fa9565b6102336110f8565b610252611160565b610233600480360360608110156105b657600080fd5b50600160a060020a03813581169160208101359091169060400135611166565b61054e611286565b6105e6611296565b604080519115158252519081900360200190f35b6102336004803603602081101561061057600080fd5b50356112a7565b6102336004803603608081101561062d57600080fd5b50600160a060020a03813581169160208101358216916040820135169060600135611300565b6105e66004803603602081101561066957600080fd5b5035600160a060020a031661145d565b6102336004803603606081101561068f57600080fd5b50600160a060020a03813581169160208101359091169060400135611472565b610252600480360360408110156106c557600080fd5b50600160a060020a03813581169160200135166114ff565b610233600480360360608110156106f357600080fd5b50600160a060020a0381358116916020810135909116906040013561151c565b61071b6117bc565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561075757818101518382015260200161073f565b505050509050019250505060405180910390f35b6102336004803603602081101561078157600080fd5b5035600160a060020a031661181e565b3360009081526003602052604090205460ff166107e25760405160e560020a62461bcd02815260040180806020018281038252603f815260200180611c93603f913960400191505060405180910390fd5b83806108225760405160e560020a62461bcd028152600401808060200182810382526038815260200180611b5e6038913960400191505060405180910390fd5b8082146108635760405160e560020a62461bcd028152600401808060200182810382526046815260200180611c106046913960600191505060405180910390fd5b60005b818110156108ae576108a687878381811061087d57fe5b90506020020135600160a060020a03168686868581811061089a57fe5b90506020020135611472565b600101610866565b50505050505050565b60026020526000908152604090205481565b600160a060020a038083166000908152600560209081526040808320938516835292905220545b92915050565b3360009081526003602052604090205460ff166109475760405160e560020a62461bcd02815260040180806020018281038252603f815260200180611c93603f913960400191505060405180910390fd5b84806109875760405160e560020a62461bcd028152600401808060200182810382526034815260200180611cd26034913960400191505060405180910390fd5b8082146109c85760405160e560020a62461bcd028152600401808060200182810382526042815260200180611bce6042913960600191505060405180910390fd5b60005b81811015610a1457610a0c8888838181106109e257fe5b90506020020135600160a060020a03168787878786818110610a0057fe5b90506020020135611300565b6001016109cb565b5050505050505050565b3360009081526003602052604090205460ff16610a6f5760405160e560020a62461bcd02815260040180806020018281038252603f815260200180611c93603f913960400191505060405180910390fd5b8380610aaf5760405160e560020a62461bcd02815260040180806020018281038252602f815260200180611e81602f913960400191505060405180910390fd5b808214610af05760405160e560020a62461bcd02815260040180806020018281038252603d815260200180611d3b603d913960400191505060405180910390fd5b60005b818110156108ae57610b33878783818110610b0a57fe5b90506020020135600160a060020a031686868685818110610b2757fe5b9050602002013561151c565b600101610af3565b3360009081526003602052604090205460ff16610b8c5760405160e560020a62461bcd02815260040180806020018281038252603f815260200180611c93603f913960400191505060405180910390fd5b8380610bcc5760405160e560020a62461bcd028152600401808060200182810382526038815260200180611b966038913960400191505060405180910390fd5b808214610c0d5760405160e560020a62461bcd028152600401808060200182810382526046815260200180611b186046913960600191505060405180910390fd5b60005b818110156108ae57610c50878783818110610c2757fe5b90506020020135600160a060020a031686868685818110610c4457fe5b90506020020135611166565b600101610c10565b610c60611296565b610c6957600080fd5b600154610d7757600160a060020a03811660009081526003602052604090205460ff1615610ccb5760405160e560020a62461bcd02815260040180806020018281038252603d815260200180611c56603d913960400191505060405180910390fd5b600160a060020a0381166000818152600360209081526040808320805460ff191660019081179091556004805491820181559093527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b909201805473ffffffffffffffffffffffffffffffffffffffff191684179055815133815291517f8918da6429714f0e9c40ae7f270773e27fc8caf7a256e19807f859563b7514de9281900390910190a2610f7f565b60008036604051602001808383808284376040805191909301818103601f1901825283528051602091820120600081815260029092529290205491955090935050508115159050610e1657600082815260026020908152604091829020429081905582518581529182015281517f0e0905d1a972d476e353bdcc3e06b19a71709054c8ba01eccb7e0691eca6d374929181900390910190a15050610f7f565b600154610e2a90829063ffffffff61183816565b421015610e6b5760405160e560020a62461bcd028152600401808060200182810382526034815260200180611e146034913960400191505060405180910390fd5b6000828152600260209081526040808320839055600160a060020a0386168352600390915290205460ff1615610ed55760405160e560020a62461bcd02815260040180806020018281038252603d815260200180611c56603d913960400191505060405180910390fd5b600160a060020a0383166000818152600360209081526040808320805460ff191660019081179091556004805491820181559093527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b909201805473ffffffffffffffffffffffffffffffffffffffff191684179055815133815291517f8918da6429714f0e9c40ae7f270773e27fc8caf7a256e19807f859563b7514de9281900390910190a250505b50565b60048181548110610f8f57fe5b600091825260209091200154600160a060020a0316905081565b610fb1611296565b610fba57600080fd5b600160a060020a03811660009081526003602052604090205460ff166110145760405160e560020a62461bcd02815260040180806020018281038252603c815260200180611d78603c913960400191505060405180910390fd5b600160a060020a038116600090815260036020908152604091829020805460ff19169055600480548351818402810184019094528084526110a19385939092919083018282801561108e57602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311611070575b505050505061185190919063ffffffff16565b80516110b591600491602090910190611a74565b50604080513381529051600160a060020a038316917f1f32c1b084e2de0713b8fb16bd46bb9df710a3dbeae2f3ca93af46e016dcc6b0919081900360200190a250565b611100611296565b61110957600080fd5b60008054604051600160a060020a03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a36000805473ffffffffffffffffffffffffffffffffffffffff19169055565b60015481565b3360009081526003602052604090205460ff166111b75760405160e560020a62461bcd02815260040180806020018281038252603f815260200180611c93603f913960400191505060405180910390fd5b600160a060020a0380841660009081526005602090815260408083209386168352929052205481111561121e5760405160e560020a62461bcd028152600401808060200182810382526035815260200180611d066035913960400191505060405180910390fd5b801561128157600160a060020a0380841660009081526005602090815260408083209386168352929052205461125a908263ffffffff61188616565b600160a060020a038085166000908152600560209081526040808320938716835292905220555b505050565b600054600160a060020a03165b90565b600054600160a060020a0316331490565b6112af611296565b6112b857600080fd5b60015481116112fb5760405160e560020a62461bcd028152600401808060200182810382526039815260200180611e486039913960400191505060405180910390fd5b600155565b3360009081526003602052604090205460ff166113515760405160e560020a62461bcd02815260040180806020018281038252603f815260200180611c93603f913960400191505060405180910390fd5b801561145757600160a060020a038085166000908152600560209081526040808320938716835292905220548111156113be5760405160e560020a62461bcd028152600401808060200182810382526031815260200180611de36031913960400191505060405180910390fd5b600160a060020a038085166000908152600560209081526040808320938716835292905220546113f4908263ffffffff61188616565b600160a060020a038581166000908152600560209081526040808320888516845290915280822093909355908416815220546114309082611838565b600160a060020a038086166000908152600560209081526040808320938716835292905220555b50505050565b60036020526000908152604090205460ff1681565b3360009081526003602052604090205460ff166114c35760405160e560020a62461bcd02815260040180806020018281038252603f815260200180611c93603f913960400191505060405180910390fd5b801561128157600160a060020a0380841660009081526005602090815260408083209386168352929052205461125a908263ffffffff61183816565b600560209081526000928352604080842090915290825290205481565b3360009081526003602052604090205460ff1661156d5760405160e560020a62461bcd02815260040180806020018281038252603f815260200180611c93603f913960400191505060405180910390fd5b801561128157604080517ff7888aec000000000000000000000000000000000000000000000000000000008152600160a060020a0385166004820152306024820152905160009173eadada7c6943c223c0d4bea475a6dacc7368f8d69163f7888aec91604480820192602092909190829003018186803b1580156115f057600080fd5b505af4158015611604573d6000803e3d6000fd5b505050506040513d602081101561161a57600080fd5b5051604080517fbeabacc8000000000000000000000000000000000000000000000000000000008152600160a060020a0380881660048301528616602482015260448101859052905191925073eadada7c6943c223c0d4bea475a6dacc7368f8d69163beabacc891606480820192600092909190829003018186803b1580156116a257600080fd5b505af41580156116b6573d6000803e3d6000fd5b5050604080517ff7888aec000000000000000000000000000000000000000000000000000000008152600160a060020a038816600482015230602482015290516000935073eadada7c6943c223c0d4bea475a6dacc7368f8d6925063f7888aec91604480820192602092909190829003018186803b15801561173757600080fd5b505af415801561174b573d6000803e3d6000fd5b505050506040513d602081101561176157600080fd5b50519050611775828463ffffffff61188616565b81146117b55760405160e560020a62461bcd02815260040180806020018281038252602f815260200180611db4602f913960400191505060405180910390fd5b5050505050565b6060600480548060200260200160405190810160405280929190818152602001828054801561181457602002820191906000526020600020905b8154600160a060020a031681526001909101906020018083116117f6575b5050505050905090565b611826611296565b61182f57600080fd5b610f7f8161189b565b60008282018381101561184a57600080fd5b9392505050565b60606000806118608585611916565b915091508061186e57600080fd5b606061187a868461197a565b5093506108f092505050565b60008282111561189557600080fd5b50900390565b600160a060020a0381166118ae57600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b81516000908190815b818110156119695784600160a060020a031686828151811061193d57fe5b6020026020010151600160a060020a03161415611961579250600191506119739050565b60010161191f565b5060009250829150505b9250929050565b6060600080845190506060600182036040519080825280602002602001820160405280156119b2578160200160208202803883390190505b50905060005b85811015611a00578681815181106119cc57fe5b60200260200101518282815181106119e057fe5b600160a060020a03909216602092830291909101909101526001016119b8565b50600185015b82811015611a5157868181518110611a1a57fe5b6020026020010151826001830381518110611a3157fe5b600160a060020a0390921660209283029190910190910152600101611a06565b5080868681518110611a5f57fe5b60200260200101519350935050509250929050565b828054828255906000526020600020908101928215611ad6579160200282015b82811115611ad6578251825473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03909116178255602090920191600190910190611a94565b50611ae2929150611ae6565b5090565b61129391905b80821115611ae257805473ffffffffffffffffffffffffffffffffffffffff19168155600101611aec56fe5661756c742e626174636844656372656d656e74546f6b656e4f776e65723a20546f6b656e7320616e64207175616e746974696573206c656e67746873206d69736d617463685661756c742e6261746368496e6372656d656e74546f6b656e4f776e65723a20546f6b656e73206d757374206e6f7420626520656d7074795661756c742e626174636844656372656d656e74546f6b656e4f776e65723a20546f6b656e73206d757374206e6f7420626520656d7074795661756c742e62617463685472616e7366657242616c616e63653a20546f6b656e7320616e64207175616e746974696573206c656e67746873206d69736d617463685661756c742e6261746368496e6372656d656e74546f6b656e4f776e65723a20546f6b656e7320616e64207175616e746974696573206c656e67746873206d69736d61746368417574686f72697a61626c652e616464417574686f72697a6564416464726573733a204164647265737320616c72656164792072656769737465726564417574686f72697a61626c652e6f6e6c79417574686f72697a65643a2053656e646572206e6f7420696e636c7564656420696e20617574686f7269746965735661756c742e62617463685472616e7366657242616c616e63653a20546f6b656e73206d757374206e6f7420626520656d7074795661756c742e64656372656d656e74546f6b656e4f776e65723a20496e73756666696369656e7420746f6b656e2062616c616e63655661756c742e62617463685769746864726177546f3a20546f6b656e7320616e64207175616e746974696573206c656e67746873206d69736d61746368417574686f72697a61626c652e72656d6f7665417574686f72697a6564416464726573733a2041646472657373206e6f7420617574686f72697a65645661756c742e7769746864726177546f3a20496e76616c696420706f73742077697468647261772062616c616e63655661756c742e7472616e7366657242616c616e63653a20496e73756666696369656e7420746f6b656e2062616c616e636554696d654c6f636b557067726164653a2054696d65206c6f636b20706572696f64206d757374206861766520656c61707365642e54696d654c6f636b557067726164653a204e657720706572696f64206d7573742062652067726561746572207468616e206578697374696e675661756c742e62617463685769746864726177546f3a20546f6b656e73206d757374206e6f7420626520656d707479a165627a7a72305820f480fd92e3c5500732696bb72ac4c783538dc9cf7a7880b833efd8beea04f8170029

Libraries Used


Deployed Bytecode Sourcemap

34904:11004:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;34904:11004:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41825:940;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;41825:940:0;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;41825:940:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;41825:940:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;41825:940:0;;;;-1:-1:-1;;;;;41825:940:0;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;41825:940:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;41825:940:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;-1:-1;41825:940:0;;-1:-1:-1;41825:940:0;-1:-1:-1;41825:940:0;:::i;:::-;;16913:53;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;16913:53:0;;:::i;:::-;;;;;;;;;;;;;;;;45669:236;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;45669:236:0;;;;;;;;;;:::i;44488:966::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;44488:966:0;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;44488:966:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;44488:966:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;44488:966:0;;;;-1:-1:-1;;;;;44488:966:0;;;;;;;;;;;;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;44488:966:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;44488:966:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;-1:-1;44488:966:0;;-1:-1:-1;44488:966:0;-1:-1:-1;44488:966:0;:::i;40548:898::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;40548:898:0;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;40548:898:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;40548:898:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;40548:898:0;;;;-1:-1:-1;;;;;40548:898:0;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;40548:898:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;40548:898:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;-1:-1;40548:898:0;;-1:-1:-1;40548:898:0;-1:-1:-1;40548:898:0;:::i;43145:940::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;43145:940:0;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;43145:940:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;43145:940:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;43145:940:0;;;;-1:-1:-1;;;;;43145:940:0;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;43145:940:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;43145:940:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;-1:-1;43145:940:0;;-1:-1:-1;43145:940:0;-1:-1:-1;43145:940:0;:::i;21435:642::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21435:642:0;-1:-1:-1;;;;;21435:642:0;;:::i;20478:28::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;20478:28:0;;:::i;:::-;;;;-1:-1:-1;;;;;20478:28:0;;;;;;;;;;;;;;22252:596;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;22252:596:0;-1:-1:-1;;;;;22252:596:0;;:::i;3531:140::-;;;:::i;16814:29::-;;;:::i;38342:630::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;38342:630:0;;;;;;;;;;;;;;;;;:::i;2741:79::-;;;:::i;3076:92::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;18745:409;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;18745:409:0;;:::i;39363:827::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;;39363:827:0;;;;;;;;;;;;;;;;;;;;;;:::i;20388:43::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;20388:43:0;-1:-1:-1;;;;;20388:43:0;;:::i;37602:379::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;37602:379:0;;;;;;;;;;;;;;;;;:::i;35708:65::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;35708:65:0;;;;;;;;;;:::i;36177:1066::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;36177:1066:0;;;;;;;;;;;;;;;;;:::i;23030:193::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;23030:193:0;;;;;;;;;;;;;;;;;3848:109;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;3848:109:0;-1:-1:-1;;;;;3848:109:0;;:::i;41825:940::-;20707:10;20696:22;;;;:10;:22;;;;;;;;20674:135;;;;-1:-1:-1;;;;;20674:135:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42120:7;42227:14;42205:120;;;;-1:-1:-1;;;;;42205:120:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42426:32;;;42404:152;;;;-1:-1:-1;;;;;42404:152:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42574:9;42569:189;42593:10;42589:1;:14;42569:189;;;42625:121;42663:7;;42671:1;42663:10;;;;;;;;;;;;;-1:-1:-1;;;;;42663:10:0;42692:6;42717:11;;42729:1;42717:14;;;;;;;;;;;;;42625:19;:121::i;:::-;42605:3;;42569:189;;;;20820:1;41825:940;;;;;:::o;16913:53::-;;;;;;;;;;;;;:::o;45669:236::-;-1:-1:-1;;;;;45873:16:0;;;45801:7;45873:16;;;:8;:16;;;;;;;;:24;;;;;;;;;;45669:236;;;;;:::o;44488:966::-;20707:10;20696:22;;;;:10;:22;;;;;;;;20674:135;;;;-1:-1:-1;;;;;20674:135:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44800:7;44907:14;44885:116;;;;-1:-1:-1;;;;;44885:116:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45102:32;;;45080:148;;;;-1:-1:-1;;;;;45080:148:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45246:9;45241:206;45265:10;45261:1;:14;45241:206;;;45297:138;45331:7;;45339:1;45331:10;;;;;;;;;;;;;-1:-1:-1;;;;;45331:10:0;45360:5;45384:3;45406:11;;45418:1;45406:14;;;;;;;;;;;;;45297:15;:138::i;:::-;45277:3;;45241:206;;;;20820:1;44488:966;;;;;;:::o;40548:898::-;20707:10;20696:22;;;;:10;:22;;;;;;;;20674:135;;;;-1:-1:-1;;;;;20674:135:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40831:7;40938:14;40916:111;;;;-1:-1:-1;;;;;40916:111:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41128:32;;;41106:143;;;;-1:-1:-1;;;;;41106:143:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41267:9;41262:177;41286:10;41282:1;:14;41262:177;;;41318:109;41347:7;;41355:1;41347:10;;;;;;;;;;;;;-1:-1:-1;;;;;41347:10:0;41376:3;41398:11;;41410:1;41398:14;;;;;;;;;;;;;41318:10;:109::i;:::-;41298:3;;41262:177;;43145:940;20707:10;20696:22;;;;:10;:22;;;;;;;;20674:135;;;;-1:-1:-1;;;;;20674:135:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43440:7;43547:14;43525:120;;;;-1:-1:-1;;;;;43525:120:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43746:32;;;43724:152;;;;-1:-1:-1;;;;;43724:152:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43894:9;43889:189;43913:10;43909:1;:14;43889:189;;;43945:121;43983:7;;43991:1;43983:10;;;;;;;;;;;;;-1:-1:-1;;;;;43983:10:0;44012:6;44037:11;;44049:1;44037:14;;;;;;;;;;;;;43945:19;:121::i;:::-;43925:3;;43889:189;;21435:642;2953:9;:7;:9::i;:::-;2945:18;;;;;;17367:14;;17363:76;;-1:-1:-1;;;;;21646:23:0;;;;;;:10;:23;;;;;;;;21645:24;21623:135;;;;-1:-1:-1;;;;;21623:135:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;21813:23:0;;;;;;:10;:23;;;;;;;;:30;;-1:-1:-1;;21813:30:0;21839:4;21813:30;;;;;;21901:11;27:10:-1;;23:18;;;45:23;;21901:29:0;;;;;;;;;-1:-1:-1;;21901:29:0;;;;;21990:79;;22048:10;21990:79;;;;;;;;;;;;;;17421:7;;17363:76;17620:19;17701:8;;17666:58;;;;;;;30:3:-1;22:6;14;1:33;17666:58:0;;;45:16:-1;;;;26:21;;;-1:-1;;22:32;6:49;;17666:58:0;;17642:93;;49:4:-1;17642:93:0;;;;17748:24;17775:31;;;:18;:31;;;;;;;17642:93;;-1:-1:-1;17775:31:0;;-1:-1:-1;;;17906:21:0;;17902:244;;-1:-1:-1;17902:244:0;;17944:31;;;;:18;:31;;;;;;;;;17978:15;17944:49;;;;18015:96;;;;;;;;;;;;;;;;;;;;;;18128:7;;;;17902:244;18220:14;;18199:36;;:16;;:36;:20;:36;:::i;:::-;18180:15;:55;;18158:157;;;;-1:-1:-1;;;;;18158:157:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18399:1;18365:31;;;:18;:31;;;;;;;;:35;;;-1:-1:-1;;;;;21646:23:0;;;;:10;:23;;;;;;;;21645:24;21623:135;;;;-1:-1:-1;;;;;21623:135:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;21813:23:0;;;;;;:10;:23;;;;;;;;:30;;-1:-1:-1;;21813:30:0;21839:4;21813:30;;;;;;21901:11;27:10:-1;;23:18;;;45:23;;21901:29:0;;;;;;;;;-1:-1:-1;;21901:29:0;;;;;21990:79;;22048:10;21990:79;;;;;;;;;;;;;;2974:1;;;21435:642;:::o;20478:28::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;20478:28:0;;-1:-1:-1;20478:28:0;:::o;22252:596::-;2953:9;:7;:9::i;:::-;2945:18;;;;;;-1:-1:-1;;;;;22423:23:0;;;;;;:10;:23;;;;;;;;22401:133;;;;-1:-1:-1;;;;;22401:133:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;22598:23:0;;22624:5;22598:23;;;:10;:23;;;;;;;;;:31;;-1:-1:-1;;22598:31:0;;;22656:11;:18;;;;;;;;;;;;;;;;;:31;;22609:11;;22656:18;;:11;:18;;;:11;:18;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;22656:18:0;;;;;;;;;;;;;;;;;;;;;;;:31;;;;:::i;:::-;22642:45;;;;:11;;:45;;;;;;:::i;:::-;-1:-1:-1;22754:86:0;;;22819:10;22754:86;;;;-1:-1:-1;;;;;22754:86:0;;;;;;;;;;;;;22252:596;:::o;3531:140::-;2953:9;:7;:9::i;:::-;2945:18;;;;;;3630:1;3614:6;;3593:40;;-1:-1:-1;;;;;3614:6:0;;;;3593:40;;3630:1;;3593:40;3661:1;3644:19;;-1:-1:-1;;3644:19:0;;;3531:140::o;16814:29::-;;;;:::o;38342:630::-;20707:10;20696:22;;;;:10;:22;;;;;;;;20674:135;;;;-1:-1:-1;;;;;20674:135:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;38627:16:0;;;;;;;:8;:16;;;;;;;;:24;;;;;;;;;;:37;-1:-1:-1;38627:37:0;38605:140;;;;-1:-1:-1;;;;;38605:140:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38762:13;;38758:207;;-1:-1:-1;;;;;38914:16:0;;;;;;;:8;:16;;;;;;;;:24;;;;;;;;;;:39;;38943:9;38914:39;:28;:39;:::i;:::-;-1:-1:-1;;;;;38887:16:0;;;;;;;:8;:16;;;;;;;;:24;;;;;;;;;:66;38758:207;38342:630;;;:::o;2741:79::-;2779:7;2806:6;-1:-1:-1;;;;;2806:6:0;2741:79;;:::o;3076:92::-;3116:4;3154:6;-1:-1:-1;;;;;3154:6:0;3140:10;:20;;3076:92::o;18745:409::-;2953:9;:7;:9::i;:::-;2945:18;;;;;;19002:14;;18984:15;:32;18962:139;;;;-1:-1:-1;;;;;18962:139:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19114:14;:32;18745:409::o;39363:827::-;20707:10;20696:22;;;;:10;:22;;;;;;;;20674:135;;;;-1:-1:-1;;;;;20674:135:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39554:13;;39550:633;;-1:-1:-1;;;;;39707:16:0;;;;;;;:8;:16;;;;;;;;:23;;;;;;;;;;:36;-1:-1:-1;39707:36:0;39681:147;;;;-1:-1:-1;;;;;39681:147:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;39966:16:0;;;;;;;:8;:16;;;;;;;;:23;;;;;;;;;;:38;;39994:9;39966:38;:27;:38;:::i;:::-;-1:-1:-1;;;;;39940:16:0;;;;;;;:8;:16;;;;;;;;:23;;;;;;;;;;;:64;;;;40135:21;;;;;;;:36;;40161:9;40135:25;:36::i;:::-;-1:-1:-1;;;;;40111:16:0;;;;;;;:8;:16;;;;;;;;:21;;;;;;;;;:60;39550:633;39363:827;;;;:::o;20388:43::-;;;;;;;;;;;;;;;:::o;37602:379::-;20707:10;20696:22;;;;:10;:22;;;;;;;;20674:135;;;;-1:-1:-1;;;;;20674:135:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37776:13;;37772:202;;-1:-1:-1;;;;;37923:16:0;;;;;;;:8;:16;;;;;;;;:24;;;;;;;;;;:39;;37952:9;37923:39;:28;:39;:::i;35708:65::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;36177:1066::-;20707:10;20696:22;;;;:10;:22;;;;;;;;20674:135;;;;-1:-1:-1;;;;;20674:135:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36339:13;;36335:901;;36464:94;;;;;;-1:-1:-1;;;;;36464:94:0;;;;;;36538:4;36464:94;;;;;;36433:28;;36464:12;;:22;;:94;;;;;;;;;;;;;;;:12;:94;;;5:2:-1;;;;30:1;27;20:12;5:2;36464:94:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;36464:94:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;36464:94:0;36665:111;;;;;;-1:-1:-1;;;;;36665:111:0;;;;;;;;;;;;;;;;;;;;;36464:94;;-1:-1:-1;36665:12:0;;:21;;:111;;;;;-1:-1:-1;;36665:111:0;;;;;;;;:12;:111;;;5:2:-1;;;;30:1;27;20:12;5:2;36665:111:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;36884:94:0;;;;;;-1:-1:-1;;;;;36884:94:0;;;;;;36958:4;36884:94;;;;;;36858:23;;-1:-1:-1;36884:12:0;;-1:-1:-1;36884:22:0;;:94;;;;;;;;;;;;;;;:12;:94;;;5:2:-1;;;;30:1;27;20:12;5:2;36884:94:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;36884:94:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;36884:94:0;;-1:-1:-1;37106:35:0;:20;37131:9;37106:35;:24;:35;:::i;:::-;37087:15;:54;37061:163;;;;-1:-1:-1;;;;;37061:163:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36335:901;;36177:1066;;;:::o;23030:193::-;23114:16;23204:11;23197:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;23197:18:0;;;;;;;;;;;;;;;;;;;;;;;23030:193;:::o;3848:109::-;2953:9;:7;:9::i;:::-;2945:18;;;;;;3921:28;3940:8;3921:18;:28::i;1550:150::-;1608:7;1640:5;;;1664:6;;;;1656:15;;;;;;1691:1;1550:150;-1:-1:-1;;;1550:150:0:o;12272:332::-;12369:16;12404:13;12419:9;12432:13;12440:1;12443;12432:7;:13::i;:::-;12403:42;;;;12461:4;12456:141;;12482:8;;;12456:141;12524:19;12548:13;12552:1;12555:5;12548:3;:13::i;:::-;-1:-1:-1;12523:38:0;-1:-1:-1;12576:9:0;;-1:-1:-1;;;12576:9:0;1312:150;1370:7;1403:1;1398;:6;;1390:15;;;;;;-1:-1:-1;1428:5:0;;;1312:150::o;4107:187::-;-1:-1:-1;;;;;4181:22:0;;4173:31;;;;;;4241:6;;;4220:38;;-1:-1:-1;;;;;4220:38:0;;;;4241:6;;;4220:38;;;4269:6;:17;;-1:-1:-1;;4269:17:0;-1:-1:-1;;;;;4269:17:0;;;;;;;;;;4107:187::o;4872:297::-;4986:8;;4943:7;;;;;5005:129;5029:6;5025:1;:10;5005:129;;;5069:1;-1:-1:-1;;;;;5061:9:0;:1;5063;5061:4;;;;;;;;;;;;;;-1:-1:-1;;;;;5061:9:0;;5057:66;;;5099:1;-1:-1:-1;5102:4:0;;-1:-1:-1;5091:16:0;;-1:-1:-1;5091:16:0;5057:66;5037:3;;5005:129;;;-1:-1:-1;5152:1:0;;-1:-1:-1;5152:1:0;;-1:-1:-1;;4872:297:0;;;;;;:::o;11721:487::-;11819:16;11837:7;11862:14;11879:1;:8;11862:25;;11898:29;11953:1;11944:6;:10;11930:25;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;11930:25:0;-1:-1:-1;11898:57:0;-1:-1:-1;11971:9:0;11966:85;11990:5;11986:1;:9;11966:85;;;12035:1;12037;12035:4;;;;;;;;;;;;;;12017:12;12030:1;12017:15;;;;;;;;-1:-1:-1;;;;;12017:22:0;;;:15;;;;;;;;;;;:22;11997:3;;11966:85;;;-1:-1:-1;12086:1:0;12078:9;;12061:98;12093:6;12089:1;:10;12061:98;;;12143:1;12145;12143:4;;;;;;;;;;;;;;12121:12;12138:1;12134;:5;12121:19;;;;;;;;-1:-1:-1;;;;;12121:26:0;;;:19;;;;;;;;;;;:26;12101:3;;12061:98;;;;12177:12;12191:1;12193:5;12191:8;;;;;;;;;;;;;;12169:31;;;;;;11721:487;;;;;:::o;34904:11004::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;34904:11004:0;-1:-1:-1;;;;;34904:11004:0;;;;;;;;;;;-1:-1:-1;34904:11004:0;;;;;;;-1:-1:-1;34904:11004:0;;;-1:-1:-1;34904:11004:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;-1:-1:-1;;34904:11004:0;;;;;;

Swarm Source

bzzr://f480fd92e3c5500732696bb72ac4c783538dc9cf7a7880b833efd8beea04f817

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
Chain Token Portfolio % Price Amount Value
ETH78.85%$3,393.97572.3377$1,942,496.82
ETH11.90%$93,8083.1251$293,162.76
ETH4.85%$23.94,994.1521$119,360.24
ETH1.91%$18.012,607.2547$46,956.66
ETH1.13%$83.24333.045$27,722.66
ETH0.79%$0.024433793,851.7827$19,396.04
ETH0.39%$0.024092402,595.879$9,699.36
ETH0.12%$13,031.405$3,031.4
ETH0.06%$0.999521,449.4539$1,448.76
ETH<0.01%$9.3920$187.8
ETH<0.01%$0.46822247.7608$22.36
ETH<0.01%$0.20868776.9556$16.06
ETH<0.01%$0.036763386.1529$14.2
ETH<0.01%$2.135.16$10.99
ETH<0.01%$0.55495713.1803$7.31
ETH<0.01%$0.4826428.6$4.15
ETH<0.01%$0.0596632.5462$1.94
ETH<0.01%$1.021.59$1.62
ETH<0.01%$0.00003925,000$0.9732
ETH<0.01%$0.4942131.93$0.9538
ETH<0.01%$1.510.442$0.6674
ETH<0.01%$0.4794611.092$0.5235
ETH<0.01%$0.00473594.1088$0.4455
ETH<0.01%$0.00244341.2899$0.1008
ETH<0.01%$0.0437292.2957$0.1003
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.