Contract 0xb8b7a92A716318F2CCed7eA856BE029969552582

Contract Overview

Balance:
0 Ether
Txn Hash
Method
Block
From
To
Value
0x0cdb5791f48ef23e7cf6c3f95456d5133ff5f061ffd51c2a0f29d7f8a7c9b686Change Owner109359492021-08-31 6:37:23353 days 16 hrs ago0xdaeca4f52c4be0d6e7de675c2feb4c3006a96c84 IN  0xb8b7a92a716318f2cced7ea856be0299695525820 Ether0.00006463 1.88180001
0x95c88d714728b2ce14e0d5cb305d63a11db63c2f00d89e774ca3e00b298fbb1cWithdraw108342792021-08-14 8:07:53370 days 15 hrs ago0xb4d695a1d0e447b26c2836295df9a0d24cac9c88 IN  0xb8b7a92a716318f2cced7ea856be0299695525820 Ether0.0011814.00000001
0x7a9a37bb21bc1643e027bc14e5fb320b818ec3606787a42ba0246c194c73f755Withdraw108342762021-08-14 8:07:15370 days 15 hrs ago0xd5f4dde0922c2f32be213d0bd840e5190da7e3b1 IN  0xb8b7a92a716318f2cced7ea856be0299695525820 Ether0.00120024.00000001
0x8ca6facb7dbadfbe3de4464483563b86fe95650633f8079978268e3ecbb55cc6Withdraw108342722021-08-14 8:05:56370 days 15 hrs ago0xfd805064bce50291c79f2beeb701b7cccd4d9b21 IN  0xb8b7a92a716318f2cced7ea856be0299695525820 Ether0.0011814
0xe06712cd107602fab2f22c1ef84109448f0c95b27a882c30d563f29c735a119fWithdraw108342702021-08-14 8:05:09370 days 15 hrs ago0xd5f4dde0922c2f32be213d0bd840e5190da7e3b1 IN  0xb8b7a92a716318f2cced7ea856be0299695525820 Ether0.001124684
0x4fb6eb8abc63bb6b04c0b6cf09cd56ffa175535d5330bcf04bc3cc75f8aa3d6eWithdraw108342702021-08-14 8:05:09370 days 15 hrs ago0x8beba386a3c80294f56d6027d3c5e5a4a5e4fcc1 IN  0xb8b7a92a716318f2cced7ea856be0299695525820 Ether0.0011814
0x305e875688c6f737296e4200616ff9d9d2b75c0d7822f0c8aeb67b2410167cd0Withdraw108342542021-08-14 8:01:34370 days 15 hrs ago0xb4afb566a3446565e9693174ed3e658256fbf0c7 IN  0xb8b7a92a716318f2cced7ea856be0299695525820 Ether0.001113444
0xf3dfbe5ec456a4388d0beced12971109c812df1f525ea0c91e494617667e61e0Withdraw108342542021-08-14 8:01:34370 days 15 hrs ago0x71c57ed3421d9f11efcbfc1f80126938da9a973a IN  0xb8b7a92a716318f2cced7ea856be0299695525820 Ether0.0011814
0x702dc88b1f9a2a7b50a393d3e7a4bf45a31c40456ed457bc47cfdd330b3e644aWithdraw108342302021-08-14 7:57:16370 days 15 hrs ago0xb4afb566a3446565e9693174ed3e658256fbf0c7 IN  0xb8b7a92a716318f2cced7ea856be0299695525820 Ether0.000120284
0x4b9096a2bb30db2d5b989d50adcd6954fe7500332dc8a5d60f3c294ad42c0664Withdraw108342262021-08-14 7:56:20370 days 15 hrs ago0x262a038d0bc05b4112c7d58bbfd407810bcfe2ab IN  0xb8b7a92a716318f2cced7ea856be0299695525820 Ether0.001192244
0x2b055017eb5d99e66d8f89bde21842bbf701cb4eb4ad49126c7d514bd11c0e98Withdraw108342242021-08-14 7:55:30370 days 15 hrs ago0xb4afb566a3446565e9693174ed3e658256fbf0c7 IN  0xb8b7a92a716318f2cced7ea856be0299695525820 Ether0.0011814
0x5c13f59e2c81cfa94e1af9b31a78172c853ae5a343d1bd7807083c4f7e32eba0Withdraw108342222021-08-14 7:54:59370 days 15 hrs ago0xb4afb566a3446565e9693174ed3e658256fbf0c7 IN  0xb8b7a92a716318f2cced7ea856be0299695525820 Ether0.00120024
0x1f91e33afcdb5ac77a8bc0d702e59bba45c69cafc6322971f93e28569dca2e94Withdraw108342152021-08-14 7:53:24370 days 15 hrs ago0xb4afb566a3446565e9693174ed3e658256fbf0c7 IN  0xb8b7a92a716318f2cced7ea856be0299695525820 Ether0.001192244.00000001
0xef2e7691c39038e8d3bc3c4e71f0dafbd353e313c97df32cdf1098fd05d4d061Withdraw108342122021-08-14 7:52:13370 days 15 hrs ago0xb4afb566a3446565e9693174ed3e658256fbf0c7 IN  0xb8b7a92a716318f2cced7ea856be0299695525820 Ether0.000120334
0xa999a2a8deeecd0b73d2aad67543bd130b3e0902ee4108681fbc8e6dfc5a36c8Withdraw108277852021-08-13 9:52:00371 days 13 hrs ago0x262a038d0bc05b4112c7d58bbfd407810bcfe2ab IN  0xb8b7a92a716318f2cced7ea856be0299695525820 Ether0.000560541.96235041
0x1200d548c66291041cce083366de15641d413d752b6bc1384952c56156875fe3Withdraw108274662021-08-13 8:44:40371 days 14 hrs ago0x262a038d0bc05b4112c7d58bbfd407810bcfe2ab IN  0xb8b7a92a716318f2cced7ea856be0299695525820 Ether0.000560981.9638877
0x2c81a3533707a8c986144c6fc5740b29ca241024296f4828dda5775ab2a4cb58Withdraw108266672021-08-13 5:43:55371 days 17 hrs ago0x262a038d0bc05b4112c7d58bbfd407810bcfe2ab IN  0xb8b7a92a716318f2cced7ea856be0299695525820 Ether0.000571291.99999991
0x00bdfbcd6cfafd0065822edd4462975737b9ddc326140e9ab3c278d4018e91adWithdraw108265902021-08-13 5:26:06371 days 17 hrs ago0x262a038d0bc05b4112c7d58bbfd407810bcfe2ab IN  0xb8b7a92a716318f2cced7ea856be0299695525820 Ether0.000565551.99999992
0x67da842ee3e5230df585b7e3d1c33ce8aa4a0f7b378b7a75d2f254c736980786Withdraw108264742021-08-13 4:51:50371 days 18 hrs ago0x262a038d0bc05b4112c7d58bbfd407810bcfe2ab IN  0xb8b7a92a716318f2cced7ea856be0299695525820 Ether0.000599751.99999997
0x1a892742aebf9c18b05bf04a0265f3325bda6c2aaf5af13b54fad6f13c1d5b39Set Storage100419232021-04-15 1:32:40491 days 21 hrs ago0xdaeca4f52c4be0d6e7de675c2feb4c3006a96c84 IN  0xb8b7a92a716318f2cced7ea856be0299695525820 Ether0.0004607410
0xf67cde86d6d406c509f2a1bfadda18a19d8c9f521793c966ac3ce13b6fbda7090x60806040100419202021-04-15 1:31:38491 days 21 hrs ago0xdaeca4f52c4be0d6e7de675c2feb4c3006a96c84 IN  Contract Creation0 Ether0.0302178910
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x0cdb5791f48ef23e7cf6c3f95456d5133ff5f061ffd51c2a0f29d7f8a7c9b686109359492021-08-31 6:37:23353 days 16 hrs ago 0xb8b7a92a716318f2cced7ea856be029969552582 0xbe53febed33be06fbb21b658f1313cc370ad46130 Ether
0xf62187f3afce4d5df3d0776da76c3fc7ed9383e1e0a5f37b18b2fa9d28acf5cc108344052021-08-14 8:39:42370 days 14 hrs ago 0xb8b7a92a716318f2cced7ea856be029969552582 0xbe53febed33be06fbb21b658f1313cc370ad46130 Ether
0xf62187f3afce4d5df3d0776da76c3fc7ed9383e1e0a5f37b18b2fa9d28acf5cc108344052021-08-14 8:39:42370 days 14 hrs ago 0xb8b7a92a716318f2cced7ea856be029969552582 0xbe53febed33be06fbb21b658f1313cc370ad46130 Ether
0xf62187f3afce4d5df3d0776da76c3fc7ed9383e1e0a5f37b18b2fa9d28acf5cc108344052021-08-14 8:39:42370 days 14 hrs ago 0xb8b7a92a716318f2cced7ea856be029969552582 0xbe53febed33be06fbb21b658f1313cc370ad46130 Ether
0xf62187f3afce4d5df3d0776da76c3fc7ed9383e1e0a5f37b18b2fa9d28acf5cc108344052021-08-14 8:39:42370 days 14 hrs ago 0xb8b7a92a716318f2cced7ea856be029969552582 0xbe53febed33be06fbb21b658f1313cc370ad46130 Ether
0xf62187f3afce4d5df3d0776da76c3fc7ed9383e1e0a5f37b18b2fa9d28acf5cc108344052021-08-14 8:39:42370 days 14 hrs ago 0xb8b7a92a716318f2cced7ea856be029969552582 0xbe53febed33be06fbb21b658f1313cc370ad46130 Ether
0xf62187f3afce4d5df3d0776da76c3fc7ed9383e1e0a5f37b18b2fa9d28acf5cc108344052021-08-14 8:39:42370 days 14 hrs ago 0x871faee277bc6d7a695566f6f60c22cd9d8714ef 0xb8b7a92a716318f2cced7ea856be0299695525820 Ether
0xf62187f3afce4d5df3d0776da76c3fc7ed9383e1e0a5f37b18b2fa9d28acf5cc108344052021-08-14 8:39:42370 days 14 hrs ago 0xb8b7a92a716318f2cced7ea856be029969552582 0x871faee277bc6d7a695566f6f60c22cd9d8714ef0 Ether
0xf62187f3afce4d5df3d0776da76c3fc7ed9383e1e0a5f37b18b2fa9d28acf5cc108344052021-08-14 8:39:42370 days 14 hrs ago 0xb8b7a92a716318f2cced7ea856be029969552582 0xd6d07f1c048bdf2b3d5d9b6c25ed1fc5348d0a700 Ether
0xf62187f3afce4d5df3d0776da76c3fc7ed9383e1e0a5f37b18b2fa9d28acf5cc108344052021-08-14 8:39:42370 days 14 hrs ago 0xb8b7a92a716318f2cced7ea856be029969552582 0xbe53febed33be06fbb21b658f1313cc370ad46130 Ether
0xf62187f3afce4d5df3d0776da76c3fc7ed9383e1e0a5f37b18b2fa9d28acf5cc108344052021-08-14 8:39:42370 days 14 hrs ago 0xb8b7a92a716318f2cced7ea856be029969552582 0xbe53febed33be06fbb21b658f1313cc370ad46130 Ether
0xf62187f3afce4d5df3d0776da76c3fc7ed9383e1e0a5f37b18b2fa9d28acf5cc108344052021-08-14 8:39:42370 days 14 hrs ago 0xb8b7a92a716318f2cced7ea856be029969552582 0xbe53febed33be06fbb21b658f1313cc370ad46130 Ether
0xf62187f3afce4d5df3d0776da76c3fc7ed9383e1e0a5f37b18b2fa9d28acf5cc108344052021-08-14 8:39:42370 days 14 hrs ago 0xb8b7a92a716318f2cced7ea856be029969552582 0xbe53febed33be06fbb21b658f1313cc370ad46130 Ether
0xf62187f3afce4d5df3d0776da76c3fc7ed9383e1e0a5f37b18b2fa9d28acf5cc108344052021-08-14 8:39:42370 days 14 hrs ago 0xb8b7a92a716318f2cced7ea856be029969552582 0xbe53febed33be06fbb21b658f1313cc370ad46130 Ether
0xf62187f3afce4d5df3d0776da76c3fc7ed9383e1e0a5f37b18b2fa9d28acf5cc108344052021-08-14 8:39:42370 days 14 hrs ago 0xb8b7a92a716318f2cced7ea856be029969552582 0xbe53febed33be06fbb21b658f1313cc370ad46130 Ether
0xf62187f3afce4d5df3d0776da76c3fc7ed9383e1e0a5f37b18b2fa9d28acf5cc108344052021-08-14 8:39:42370 days 14 hrs ago 0xb8b7a92a716318f2cced7ea856be029969552582 0xbe53febed33be06fbb21b658f1313cc370ad46130 Ether
0xf62187f3afce4d5df3d0776da76c3fc7ed9383e1e0a5f37b18b2fa9d28acf5cc108344052021-08-14 8:39:42370 days 14 hrs ago 0xb8b7a92a716318f2cced7ea856be029969552582 0xbe53febed33be06fbb21b658f1313cc370ad46130 Ether
0xf62187f3afce4d5df3d0776da76c3fc7ed9383e1e0a5f37b18b2fa9d28acf5cc108344052021-08-14 8:39:42370 days 14 hrs ago 0xb8b7a92a716318f2cced7ea856be029969552582 0xbe53febed33be06fbb21b658f1313cc370ad46130 Ether
0xf62187f3afce4d5df3d0776da76c3fc7ed9383e1e0a5f37b18b2fa9d28acf5cc108344052021-08-14 8:39:42370 days 14 hrs ago 0xb8b7a92a716318f2cced7ea856be029969552582 0xbe53febed33be06fbb21b658f1313cc370ad46130 Ether
0xf62187f3afce4d5df3d0776da76c3fc7ed9383e1e0a5f37b18b2fa9d28acf5cc108344052021-08-14 8:39:42370 days 14 hrs ago 0xb8b7a92a716318f2cced7ea856be029969552582 0xbe53febed33be06fbb21b658f1313cc370ad46130 Ether
0xf62187f3afce4d5df3d0776da76c3fc7ed9383e1e0a5f37b18b2fa9d28acf5cc108344052021-08-14 8:39:42370 days 14 hrs ago 0xb8b7a92a716318f2cced7ea856be029969552582 0xbe53febed33be06fbb21b658f1313cc370ad46130 Ether
0xf62187f3afce4d5df3d0776da76c3fc7ed9383e1e0a5f37b18b2fa9d28acf5cc108344052021-08-14 8:39:42370 days 14 hrs ago 0xb8b7a92a716318f2cced7ea856be029969552582 0xbe53febed33be06fbb21b658f1313cc370ad46130 Ether
0xf62187f3afce4d5df3d0776da76c3fc7ed9383e1e0a5f37b18b2fa9d28acf5cc108344052021-08-14 8:39:42370 days 14 hrs ago 0xb8b7a92a716318f2cced7ea856be029969552582 0xbe53febed33be06fbb21b658f1313cc370ad46130 Ether
0xf62187f3afce4d5df3d0776da76c3fc7ed9383e1e0a5f37b18b2fa9d28acf5cc108344052021-08-14 8:39:42370 days 14 hrs ago 0xb8b7a92a716318f2cced7ea856be029969552582 0xbe53febed33be06fbb21b658f1313cc370ad46130 Ether
0xf62187f3afce4d5df3d0776da76c3fc7ed9383e1e0a5f37b18b2fa9d28acf5cc108344052021-08-14 8:39:42370 days 14 hrs ago 0xb8b7a92a716318f2cced7ea856be029969552582 0xbe53febed33be06fbb21b658f1313cc370ad46130 Ether
[ Download CSV Export 
Loading

Similar Match Source Code
Note: This contract matches the deployed ByteCode of the Source Code for Contract 0xa491b99008947f0b48cc03eb59d286de583008aa

Contract Name:
Lockup

Compiler Version
v0.5.17+commit.d19bba13

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MPL-2.0 license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-04-13
*/

// File: @openzeppelin/contracts/math/SafeMath.sol

pragma solidity ^0.5.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     *
     * _Available since v2.4.0._
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot 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-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     *
     * _Available since v2.4.0._
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     *
     * _Available since v2.4.0._
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

// File: contracts/src/common/libs/Decimals.sol

pragma solidity 0.5.17;


/**
 * Library for emulating calculations involving decimals.
 */
library Decimals {
	using SafeMath for uint256;
	uint120 private constant BASIS_VAKUE = 1000000000000000000;

	/**
	 * @dev Returns the ratio of the first argument to the second argument.
	 * @param _a Numerator.
	 * @param _b Fraction.
	 * @return Calculated ratio.
	 */
	function outOf(uint256 _a, uint256 _b)
		internal
		pure
		returns (uint256 result)
	{
		if (_a == 0) {
			return 0;
		}
		uint256 a = _a.mul(BASIS_VAKUE);
		if (a < _b) {
			return 0;
		}
		return (a.div(_b));
	}

	/**
	 * @dev Returns multiplied the number by 10^18.
	 * @param _a Numerical value to be multiplied.
	 * @return Multiplied value.
	 */
	function mulBasis(uint256 _a) internal pure returns (uint256) {
		return _a.mul(BASIS_VAKUE);
	}

	/**
	 * @dev Returns divisioned the number by 10^18.
	 * This function can use it to restore the number of digits in the result of `outOf`.
	 * @param _a Numerical value to be divisioned.
	 * @return Divisioned value.
	 */
	function divBasis(uint256 _a) internal pure returns (uint256) {
		return _a.div(BASIS_VAKUE);
	}
}

// File: contracts/interface/IAddressConfig.sol

// SPDX-License-Identifier: MPL-2.0
pragma solidity >=0.5.17;

interface IAddressConfig {
	function token() external view returns (address);

	function allocator() external view returns (address);

	function allocatorStorage() external view returns (address);

	function withdraw() external view returns (address);

	function withdrawStorage() external view returns (address);

	function marketFactory() external view returns (address);

	function marketGroup() external view returns (address);

	function propertyFactory() external view returns (address);

	function propertyGroup() external view returns (address);

	function metricsGroup() external view returns (address);

	function metricsFactory() external view returns (address);

	function policy() external view returns (address);

	function policyFactory() external view returns (address);

	function policySet() external view returns (address);

	function policyGroup() external view returns (address);

	function lockup() external view returns (address);

	function lockupStorage() external view returns (address);

	function voteTimes() external view returns (address);

	function voteTimesStorage() external view returns (address);

	function voteCounter() external view returns (address);

	function voteCounterStorage() external view returns (address);

	function setAllocator(address _addr) external;

	function setAllocatorStorage(address _addr) external;

	function setWithdraw(address _addr) external;

	function setWithdrawStorage(address _addr) external;

	function setMarketFactory(address _addr) external;

	function setMarketGroup(address _addr) external;

	function setPropertyFactory(address _addr) external;

	function setPropertyGroup(address _addr) external;

	function setMetricsFactory(address _addr) external;

	function setMetricsGroup(address _addr) external;

	function setPolicyFactory(address _addr) external;

	function setPolicyGroup(address _addr) external;

	function setPolicySet(address _addr) external;

	function setPolicy(address _addr) external;

	function setToken(address _addr) external;

	function setLockup(address _addr) external;

	function setLockupStorage(address _addr) external;

	function setVoteTimes(address _addr) external;

	function setVoteTimesStorage(address _addr) external;

	function setVoteCounter(address _addr) external;

	function setVoteCounterStorage(address _addr) external;
}

// File: contracts/src/common/config/UsingConfig.sol

pragma solidity 0.5.17;


/**
 * Module for using AddressConfig contracts.
 */
contract UsingConfig {
	address private _config;

	/**
	 * Initialize the argument as AddressConfig address.
	 */
	constructor(address _addressConfig) public {
		_config = _addressConfig;
	}

	/**
	 * Returns the latest AddressConfig instance.
	 */
	function config() internal view returns (IAddressConfig) {
		return IAddressConfig(_config);
	}

	/**
	 * Returns the latest AddressConfig address.
	 */
	function configAddress() external view returns (address) {
		return _config;
	}
}

// File: contracts/interface/IUsingStorage.sol

// SPDX-License-Identifier: MPL-2.0
pragma solidity >=0.5.17;

interface IUsingStorage {
	function getStorageAddress() external view returns (address);

	function createStorage() external;

	function setStorage(address _storageAddress) external;

	function changeOwner(address newOwner) external;
}

// File: @openzeppelin/contracts/GSN/Context.sol

pragma solidity ^0.5.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with GSN meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
contract Context {
    // Empty internal constructor, to prevent people from mistakenly deploying
    // an instance of this contract, which should be used via inheritance.
    constructor () internal { }
    // solhint-disable-previous-line no-empty-blocks

    function _msgSender() internal view returns (address payable) {
        return msg.sender;
    }

    function _msgData() internal view returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

// File: @openzeppelin/contracts/ownership/Ownable.sol

pragma solidity ^0.5.0;

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
contract Ownable is Context {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () internal {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(isOwner(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Returns true if the caller is the current owner.
     */
    function isOwner() public view returns (bool) {
        return _msgSender() == _owner;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: 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 Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public onlyOwner {
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     */
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

// File: contracts/src/common/storage/EternalStorage.sol

pragma solidity 0.5.17;

/**
 * Module for persisting states.
 * Stores a map for `uint256`, `string`, `address`, `bytes32`, `bool`, and `int256` type with `bytes32` type as a key.
 */
contract EternalStorage {
	address private currentOwner = msg.sender;

	mapping(bytes32 => uint256) private uIntStorage;
	mapping(bytes32 => string) private stringStorage;
	mapping(bytes32 => address) private addressStorage;
	mapping(bytes32 => bytes32) private bytesStorage;
	mapping(bytes32 => bool) private boolStorage;
	mapping(bytes32 => int256) private intStorage;

	/**
	 * Modifiers to validate that only the owner can execute.
	 */
	modifier onlyCurrentOwner() {
		require(msg.sender == currentOwner, "not current owner");
		_;
	}

	/**
	 * Transfer the owner.
	 * Only the owner can execute this function.
	 */
	function changeOwner(address _newOwner) external {
		require(msg.sender == currentOwner, "not current owner");
		currentOwner = _newOwner;
	}

	// *** Getter Methods ***

	/**
	 * Returns the value of the `uint256` type that mapped to the given key.
	 */
	function getUint(bytes32 _key) external view returns (uint256) {
		return uIntStorage[_key];
	}

	/**
	 * Returns the value of the `string` type that mapped to the given key.
	 */
	function getString(bytes32 _key) external view returns (string memory) {
		return stringStorage[_key];
	}

	/**
	 * Returns the value of the `address` type that mapped to the given key.
	 */
	function getAddress(bytes32 _key) external view returns (address) {
		return addressStorage[_key];
	}

	/**
	 * Returns the value of the `bytes32` type that mapped to the given key.
	 */
	function getBytes(bytes32 _key) external view returns (bytes32) {
		return bytesStorage[_key];
	}

	/**
	 * Returns the value of the `bool` type that mapped to the given key.
	 */
	function getBool(bytes32 _key) external view returns (bool) {
		return boolStorage[_key];
	}

	/**
	 * Returns the value of the `int256` type that mapped to the given key.
	 */
	function getInt(bytes32 _key) external view returns (int256) {
		return intStorage[_key];
	}

	// *** Setter Methods ***

	/**
	 * Maps a value of `uint256` type to a given key.
	 * Only the owner can execute this function.
	 */
	function setUint(bytes32 _key, uint256 _value) external onlyCurrentOwner {
		uIntStorage[_key] = _value;
	}

	/**
	 * Maps a value of `string` type to a given key.
	 * Only the owner can execute this function.
	 */
	function setString(bytes32 _key, string calldata _value)
		external
		onlyCurrentOwner
	{
		stringStorage[_key] = _value;
	}

	/**
	 * Maps a value of `address` type to a given key.
	 * Only the owner can execute this function.
	 */
	function setAddress(bytes32 _key, address _value)
		external
		onlyCurrentOwner
	{
		addressStorage[_key] = _value;
	}

	/**
	 * Maps a value of `bytes32` type to a given key.
	 * Only the owner can execute this function.
	 */
	function setBytes(bytes32 _key, bytes32 _value) external onlyCurrentOwner {
		bytesStorage[_key] = _value;
	}

	/**
	 * Maps a value of `bool` type to a given key.
	 * Only the owner can execute this function.
	 */
	function setBool(bytes32 _key, bool _value) external onlyCurrentOwner {
		boolStorage[_key] = _value;
	}

	/**
	 * Maps a value of `int256` type to a given key.
	 * Only the owner can execute this function.
	 */
	function setInt(bytes32 _key, int256 _value) external onlyCurrentOwner {
		intStorage[_key] = _value;
	}

	// *** Delete Methods ***

	/**
	 * Deletes the value of the `uint256` type that mapped to the given key.
	 * Only the owner can execute this function.
	 */
	function deleteUint(bytes32 _key) external onlyCurrentOwner {
		delete uIntStorage[_key];
	}

	/**
	 * Deletes the value of the `string` type that mapped to the given key.
	 * Only the owner can execute this function.
	 */
	function deleteString(bytes32 _key) external onlyCurrentOwner {
		delete stringStorage[_key];
	}

	/**
	 * Deletes the value of the `address` type that mapped to the given key.
	 * Only the owner can execute this function.
	 */
	function deleteAddress(bytes32 _key) external onlyCurrentOwner {
		delete addressStorage[_key];
	}

	/**
	 * Deletes the value of the `bytes32` type that mapped to the given key.
	 * Only the owner can execute this function.
	 */
	function deleteBytes(bytes32 _key) external onlyCurrentOwner {
		delete bytesStorage[_key];
	}

	/**
	 * Deletes the value of the `bool` type that mapped to the given key.
	 * Only the owner can execute this function.
	 */
	function deleteBool(bytes32 _key) external onlyCurrentOwner {
		delete boolStorage[_key];
	}

	/**
	 * Deletes the value of the `int256` type that mapped to the given key.
	 * Only the owner can execute this function.
	 */
	function deleteInt(bytes32 _key) external onlyCurrentOwner {
		delete intStorage[_key];
	}
}

// File: contracts/src/common/storage/UsingStorage.sol

pragma solidity 0.5.17;




/**
 * Module for contrast handling EternalStorage.
 */
contract UsingStorage is Ownable, IUsingStorage {
	address private _storage;

	/**
	 * Modifier to verify that EternalStorage is set.
	 */
	modifier hasStorage() {
		require(_storage != address(0), "storage is not set");
		_;
	}

	/**
	 * Returns the set EternalStorage instance.
	 */
	function eternalStorage()
		internal
		view
		hasStorage
		returns (EternalStorage)
	{
		return EternalStorage(_storage);
	}

	/**
	 * Returns the set EternalStorage address.
	 */
	function getStorageAddress() external view hasStorage returns (address) {
		return _storage;
	}

	/**
	 * Create a new EternalStorage contract.
	 * This function call will fail if the EternalStorage contract is already set.
	 * Also, only the owner can execute it.
	 */
	function createStorage() external onlyOwner {
		require(_storage == address(0), "storage is set");
		EternalStorage tmp = new EternalStorage();
		_storage = address(tmp);
	}

	/**
	 * Assigns the EternalStorage contract that has already been created.
	 * Only the owner can execute this function.
	 */
	function setStorage(address _storageAddress) external onlyOwner {
		_storage = _storageAddress;
	}

	/**
	 * Delegates the owner of the current EternalStorage contract.
	 * Only the owner can execute this function.
	 */
	function changeOwner(address newOwner) external onlyOwner {
		EternalStorage(_storage).changeOwner(newOwner);
	}
}

// File: contracts/src/lockup/LockupStorage.sol

pragma solidity 0.5.17;



contract LockupStorage is UsingStorage {
	using SafeMath for uint256;

	uint256 private constant BASIS = 100000000000000000000000000000000;

	//AllValue
	function setStorageAllValue(uint256 _value) internal {
		bytes32 key = getStorageAllValueKey();
		eternalStorage().setUint(key, _value);
	}

	function getStorageAllValue() public view returns (uint256) {
		bytes32 key = getStorageAllValueKey();
		return eternalStorage().getUint(key);
	}

	function getStorageAllValueKey() private pure returns (bytes32) {
		return keccak256(abi.encodePacked("_allValue"));
	}

	//Value
	function setStorageValue(
		address _property,
		address _sender,
		uint256 _value
	) internal {
		bytes32 key = getStorageValueKey(_property, _sender);
		eternalStorage().setUint(key, _value);
	}

	function getStorageValue(address _property, address _sender)
		public
		view
		returns (uint256)
	{
		bytes32 key = getStorageValueKey(_property, _sender);
		return eternalStorage().getUint(key);
	}

	function getStorageValueKey(address _property, address _sender)
		private
		pure
		returns (bytes32)
	{
		return keccak256(abi.encodePacked("_value", _property, _sender));
	}

	//PropertyValue
	function setStoragePropertyValue(address _property, uint256 _value)
		internal
	{
		bytes32 key = getStoragePropertyValueKey(_property);
		eternalStorage().setUint(key, _value);
	}

	function getStoragePropertyValue(address _property)
		public
		view
		returns (uint256)
	{
		bytes32 key = getStoragePropertyValueKey(_property);
		return eternalStorage().getUint(key);
	}

	function getStoragePropertyValueKey(address _property)
		private
		pure
		returns (bytes32)
	{
		return keccak256(abi.encodePacked("_propertyValue", _property));
	}

	//InterestPrice
	function setStorageInterestPrice(address _property, uint256 _value)
		internal
	{
		// The previously used function
		// This function is only used in testing
		eternalStorage().setUint(getStorageInterestPriceKey(_property), _value);
	}

	function getStorageInterestPrice(address _property)
		public
		view
		returns (uint256)
	{
		return eternalStorage().getUint(getStorageInterestPriceKey(_property));
	}

	function getStorageInterestPriceKey(address _property)
		private
		pure
		returns (bytes32)
	{
		return keccak256(abi.encodePacked("_interestTotals", _property));
	}

	//LastInterestPrice
	function setStorageLastInterestPrice(
		address _property,
		address _user,
		uint256 _value
	) internal {
		eternalStorage().setUint(
			getStorageLastInterestPriceKey(_property, _user),
			_value
		);
	}

	function getStorageLastInterestPrice(address _property, address _user)
		public
		view
		returns (uint256)
	{
		return
			eternalStorage().getUint(
				getStorageLastInterestPriceKey(_property, _user)
			);
	}

	function getStorageLastInterestPriceKey(address _property, address _user)
		private
		pure
		returns (bytes32)
	{
		return
			keccak256(
				abi.encodePacked("_lastLastInterestPrice", _property, _user)
			);
	}

	//LastSameRewardsAmountAndBlock
	function setStorageLastSameRewardsAmountAndBlock(
		uint256 _amount,
		uint256 _block
	) internal {
		uint256 record = _amount.mul(BASIS).add(_block);
		eternalStorage().setUint(
			getStorageLastSameRewardsAmountAndBlockKey(),
			record
		);
	}

	function getStorageLastSameRewardsAmountAndBlock()
		public
		view
		returns (uint256 _amount, uint256 _block)
	{
		uint256 record =
			eternalStorage().getUint(
				getStorageLastSameRewardsAmountAndBlockKey()
			);
		uint256 amount = record.div(BASIS);
		uint256 blockNumber = record.sub(amount.mul(BASIS));
		return (amount, blockNumber);
	}

	function getStorageLastSameRewardsAmountAndBlockKey()
		private
		pure
		returns (bytes32)
	{
		return keccak256(abi.encodePacked("_LastSameRewardsAmountAndBlock"));
	}

	//CumulativeGlobalRewards
	function setStorageCumulativeGlobalRewards(uint256 _value) internal {
		eternalStorage().setUint(
			getStorageCumulativeGlobalRewardsKey(),
			_value
		);
	}

	function getStorageCumulativeGlobalRewards() public view returns (uint256) {
		return eternalStorage().getUint(getStorageCumulativeGlobalRewardsKey());
	}

	function getStorageCumulativeGlobalRewardsKey()
		private
		pure
		returns (bytes32)
	{
		return keccak256(abi.encodePacked("_cumulativeGlobalRewards"));
	}

	//PendingWithdrawal
	function setStoragePendingInterestWithdrawal(
		address _property,
		address _user,
		uint256 _value
	) internal {
		eternalStorage().setUint(
			getStoragePendingInterestWithdrawalKey(_property, _user),
			_value
		);
	}

	function getStoragePendingInterestWithdrawal(
		address _property,
		address _user
	) public view returns (uint256) {
		return
			eternalStorage().getUint(
				getStoragePendingInterestWithdrawalKey(_property, _user)
			);
	}

	function getStoragePendingInterestWithdrawalKey(
		address _property,
		address _user
	) private pure returns (bytes32) {
		return
			keccak256(
				abi.encodePacked("_pendingInterestWithdrawal", _property, _user)
			);
	}

	//DIP4GenesisBlock
	function setStorageDIP4GenesisBlock(uint256 _block) internal {
		eternalStorage().setUint(getStorageDIP4GenesisBlockKey(), _block);
	}

	function getStorageDIP4GenesisBlock() public view returns (uint256) {
		return eternalStorage().getUint(getStorageDIP4GenesisBlockKey());
	}

	function getStorageDIP4GenesisBlockKey() private pure returns (bytes32) {
		return keccak256(abi.encodePacked("_dip4GenesisBlock"));
	}

	//lastStakedInterestPrice
	function setStorageLastStakedInterestPrice(
		address _property,
		address _user,
		uint256 _value
	) internal {
		eternalStorage().setUint(
			getStorageLastStakedInterestPriceKey(_property, _user),
			_value
		);
	}

	function getStorageLastStakedInterestPrice(address _property, address _user)
		public
		view
		returns (uint256)
	{
		return
			eternalStorage().getUint(
				getStorageLastStakedInterestPriceKey(_property, _user)
			);
	}

	function getStorageLastStakedInterestPriceKey(
		address _property,
		address _user
	) private pure returns (bytes32) {
		return
			keccak256(
				abi.encodePacked("_lastStakedInterestPrice", _property, _user)
			);
	}

	//lastStakesChangedCumulativeReward
	function setStorageLastStakesChangedCumulativeReward(uint256 _value)
		internal
	{
		eternalStorage().setUint(
			getStorageLastStakesChangedCumulativeRewardKey(),
			_value
		);
	}

	function getStorageLastStakesChangedCumulativeReward()
		public
		view
		returns (uint256)
	{
		return
			eternalStorage().getUint(
				getStorageLastStakesChangedCumulativeRewardKey()
			);
	}

	function getStorageLastStakesChangedCumulativeRewardKey()
		private
		pure
		returns (bytes32)
	{
		return
			keccak256(abi.encodePacked("_lastStakesChangedCumulativeReward"));
	}

	//LastCumulativeHoldersRewardPrice
	function setStorageLastCumulativeHoldersRewardPrice(uint256 _holders)
		internal
	{
		eternalStorage().setUint(
			getStorageLastCumulativeHoldersRewardPriceKey(),
			_holders
		);
	}

	function getStorageLastCumulativeHoldersRewardPrice()
		public
		view
		returns (uint256)
	{
		return
			eternalStorage().getUint(
				getStorageLastCumulativeHoldersRewardPriceKey()
			);
	}

	function getStorageLastCumulativeHoldersRewardPriceKey()
		private
		pure
		returns (bytes32)
	{
		return keccak256(abi.encodePacked("0lastCumulativeHoldersRewardPrice"));
	}

	//LastCumulativeInterestPrice
	function setStorageLastCumulativeInterestPrice(uint256 _interest) internal {
		eternalStorage().setUint(
			getStorageLastCumulativeInterestPriceKey(),
			_interest
		);
	}

	function getStorageLastCumulativeInterestPrice()
		public
		view
		returns (uint256)
	{
		return
			eternalStorage().getUint(
				getStorageLastCumulativeInterestPriceKey()
			);
	}

	function getStorageLastCumulativeInterestPriceKey()
		private
		pure
		returns (bytes32)
	{
		return keccak256(abi.encodePacked("0lastCumulativeInterestPrice"));
	}

	//LastCumulativeHoldersRewardAmountPerProperty
	function setStorageLastCumulativeHoldersRewardAmountPerProperty(
		address _property,
		uint256 _value
	) internal {
		eternalStorage().setUint(
			getStorageLastCumulativeHoldersRewardAmountPerPropertyKey(
				_property
			),
			_value
		);
	}

	function getStorageLastCumulativeHoldersRewardAmountPerProperty(
		address _property
	) public view returns (uint256) {
		return
			eternalStorage().getUint(
				getStorageLastCumulativeHoldersRewardAmountPerPropertyKey(
					_property
				)
			);
	}

	function getStorageLastCumulativeHoldersRewardAmountPerPropertyKey(
		address _property
	) private pure returns (bytes32) {
		return
			keccak256(
				abi.encodePacked(
					"0lastCumulativeHoldersRewardAmountPerProperty",
					_property
				)
			);
	}

	//LastCumulativeHoldersRewardPricePerProperty
	function setStorageLastCumulativeHoldersRewardPricePerProperty(
		address _property,
		uint256 _price
	) internal {
		eternalStorage().setUint(
			getStorageLastCumulativeHoldersRewardPricePerPropertyKey(_property),
			_price
		);
	}

	function getStorageLastCumulativeHoldersRewardPricePerProperty(
		address _property
	) public view returns (uint256) {
		return
			eternalStorage().getUint(
				getStorageLastCumulativeHoldersRewardPricePerPropertyKey(
					_property
				)
			);
	}

	function getStorageLastCumulativeHoldersRewardPricePerPropertyKey(
		address _property
	) private pure returns (bytes32) {
		return
			keccak256(
				abi.encodePacked(
					"0lastCumulativeHoldersRewardPricePerProperty",
					_property
				)
			);
	}
}

// File: contracts/interface/IDevMinter.sol

// SPDX-License-Identifier: MPL-2.0
pragma solidity >=0.5.17;

interface IDevMinter {
	function mint(address account, uint256 amount) external returns (bool);
}

// File: contracts/interface/IProperty.sol

// SPDX-License-Identifier: MPL-2.0
pragma solidity >=0.5.17;

interface IProperty {
	function author() external view returns (address);

	function changeAuthor(address _nextAuthor) external;

	function changeName(string calldata _name) external;

	function changeSymbol(string calldata _symbol) external;

	function withdraw(address _sender, uint256 _value) external;
}

// File: contracts/interface/IPolicy.sol

// SPDX-License-Identifier: MPL-2.0
pragma solidity >=0.5.17;

interface IPolicy {
	function rewards(uint256 _lockups, uint256 _assets)
		external
		view
		returns (uint256);

	function holdersShare(uint256 _amount, uint256 _lockups)
		external
		view
		returns (uint256);

	function authenticationFee(uint256 _assets, uint256 _propertyAssets)
		external
		view
		returns (uint256);

	function marketApproval(uint256 _agree, uint256 _opposite)
		external
		view
		returns (bool);

	function policyApproval(uint256 _agree, uint256 _opposite)
		external
		view
		returns (bool);

	function marketVotingBlocks() external view returns (uint256);

	function policyVotingBlocks() external view returns (uint256);

	function shareOfTreasury(uint256 _supply) external view returns (uint256);

	function treasury() external view returns (address);
}

// File: contracts/interface/IAllocator.sol

// SPDX-License-Identifier: MPL-2.0
pragma solidity >=0.5.17;

interface IAllocator {
	function beforeBalanceChange(
		address _property,
		address _from,
		address _to
	) external;

	function calculateMaxRewardsPerBlock() external view returns (uint256);
}

// File: contracts/interface/ILockup.sol

// SPDX-License-Identifier: MPL-2.0
pragma solidity >=0.5.17;

interface ILockup {
	function lockup(
		address _from,
		address _property,
		uint256 _value
	) external;

	function update() external;

	function withdraw(address _property, uint256 _amount) external;

	function calculateCumulativeRewardPrices()
		external
		view
		returns (
			uint256 _reward,
			uint256 _holders,
			uint256 _interest
		);

	function calculateCumulativeHoldersRewardAmount(address _property)
		external
		view
		returns (uint256);

	function getPropertyValue(address _property)
		external
		view
		returns (uint256);

	function getAllValue() external view returns (uint256);

	function getValue(address _property, address _sender)
		external
		view
		returns (uint256);

	function calculateWithdrawableInterestAmount(
		address _property,
		address _user
	) external view returns (uint256);

	function devMinter() external view returns (address);
}

// File: contracts/interface/IMetricsGroup.sol

// SPDX-License-Identifier: MPL-2.0
pragma solidity >=0.5.17;

interface IMetricsGroup {
	function addGroup(address _addr) external;

	function removeGroup(address _addr) external;

	function isGroup(address _addr) external view returns (bool);

	function totalIssuedMetrics() external view returns (uint256);

	function hasAssets(address _property) external view returns (bool);

	function getMetricsCountPerProperty(address _property)
		external
		view
		returns (uint256);
}

// File: contracts/src/lockup/Lockup.sol

pragma solidity 0.5.17;

// prettier-ignore











/**
 * A contract that manages the staking of DEV tokens and calculates rewards.
 * Staking and the following mechanism determines that reward calculation.
 *
 * Variables:
 * -`M`: Maximum mint amount per block determined by Allocator contract
 * -`B`: Number of blocks during staking
 * -`P`: Total number of staking locked up in a Property contract
 * -`S`: Total number of staking locked up in all Property contracts
 * -`U`: Number of staking per account locked up in a Property contract
 *
 * Formula:
 * Staking Rewards = M * B * (P / S) * (U / P)
 *
 * Note:
 * -`M`, `P` and `S` vary from block to block, and the variation cannot be predicted.
 * -`B` is added every time the Ethereum block is created.
 * - Only `U` and `B` are predictable variables.
 * - As `M`, `P` and `S` cannot be observed from a staker, the "cumulative sum" is often used to calculate ratio variation with history.
 * - Reward withdrawal always withdraws the total withdrawable amount.
 *
 * Scenario:
 * - Assume `M` is fixed at 500
 * - Alice stakes 100 DEV on Property-A (Alice's staking state on Property-A: `M`=500, `B`=0, `P`=100, `S`=100, `U`=100)
 * - After 10 blocks, Bob stakes 60 DEV on Property-B (Alice's staking state on Property-A: `M`=500, `B`=10, `P`=100, `S`=160, `U`=100)
 * - After 10 blocks, Carol stakes 40 DEV on Property-A (Alice's staking state on Property-A: `M`=500, `B`=20, `P`=140, `S`=200, `U`=100)
 * - After 10 blocks, Alice withdraws Property-A staking reward. The reward at this time is 5000 DEV (10 blocks * 500 DEV) + 3125 DEV (10 blocks * 62.5% * 500 DEV) + 2500 DEV (10 blocks * 50% * 500 DEV).
 */
contract Lockup is ILockup, UsingConfig, LockupStorage {
	using SafeMath for uint256;
	using Decimals for uint256;
	address public devMinter;
	struct RewardPrices {
		uint256 reward;
		uint256 holders;
		uint256 interest;
	}
	event Lockedup(address _from, address _property, uint256 _value);

	/**
	 * Initialize the passed address as AddressConfig address and Devminter.
	 */
	constructor(address _config, address _devMinter)
		public
		UsingConfig(_config)
	{
		devMinter = _devMinter;
	}

	/**
	 * Adds staking.
	 * Only the Dev contract can execute this function.
	 */
	function lockup(
		address _from,
		address _property,
		uint256 _value
	) external {
		/**
		 * Validates the sender is Dev contract.
		 */
		require(msg.sender == config().token(), "this is illegal address");

		/**
		 * Validates _value is not 0.
		 */
		require(_value != 0, "illegal lockup value");

		/**
		 * Validates the passed Property has greater than 1 asset.
		 */
		require(
			IMetricsGroup(config().metricsGroup()).hasAssets(_property),
			"unable to stake to unauthenticated property"
		);

		/**
		 * Since the reward per block that can be withdrawn will change with the addition of staking,
		 * saves the undrawn withdrawable reward before addition it.
		 */
		RewardPrices memory prices =
			updatePendingInterestWithdrawal(_property, _from);

		/**
		 * Saves variables that should change due to the addition of staking.
		 */
		updateValues(true, _from, _property, _value, prices);
		emit Lockedup(_from, _property, _value);
	}

	/**
	 * Withdraw staking.
	 * Releases staking, withdraw rewards, and transfer the staked and withdraw rewards amount to the sender.
	 */
	function withdraw(address _property, uint256 _amount) external {
		/**
		 * Validates the sender is staking to the target Property.
		 */
		require(
			hasValue(_property, msg.sender, _amount),
			"insufficient tokens staked"
		);

		/**
		 * Withdraws the staking reward
		 */
		RewardPrices memory prices = _withdrawInterest(_property);

		/**
		 * Transfer the staked amount to the sender.
		 */
		if (_amount != 0) {
			IProperty(_property).withdraw(msg.sender, _amount);
		}

		/**
		 * Saves variables that should change due to the canceling staking..
		 */
		updateValues(false, msg.sender, _property, _amount, prices);
	}

	/**
	 * Store staking states as a snapshot.
	 */
	function beforeStakesChanged(
		address _property,
		address _user,
		RewardPrices memory _prices
	) private {
		/**
		 * Gets latest cumulative holders reward for the passed Property.
		 */
		uint256 cHoldersReward =
			_calculateCumulativeHoldersRewardAmount(_prices.holders, _property);

		/**
		 * Store each value.
		 */
		setStorageLastStakedInterestPrice(_property, _user, _prices.interest);
		setStorageLastStakesChangedCumulativeReward(_prices.reward);
		setStorageLastCumulativeHoldersRewardPrice(_prices.holders);
		setStorageLastCumulativeInterestPrice(_prices.interest);
		setStorageLastCumulativeHoldersRewardAmountPerProperty(
			_property,
			cHoldersReward
		);
		setStorageLastCumulativeHoldersRewardPricePerProperty(
			_property,
			_prices.holders
		);
	}

	/**
	 * Gets latest value of cumulative sum of the reward amount, cumulative sum of the holders reward per stake, and cumulative sum of the stakers reward per stake.
	 */
	function calculateCumulativeRewardPrices()
		public
		view
		returns (
			uint256 _reward,
			uint256 _holders,
			uint256 _interest
		)
	{
		uint256 lastReward = getStorageLastStakesChangedCumulativeReward();
		uint256 lastHoldersPrice = getStorageLastCumulativeHoldersRewardPrice();
		uint256 lastInterestPrice = getStorageLastCumulativeInterestPrice();
		uint256 allStakes = getStorageAllValue();

		/**
		 * Gets latest cumulative sum of the reward amount.
		 */
		(uint256 reward, ) = dry();
		uint256 mReward = reward.mulBasis();

		/**
		 * Calculates reward unit price per staking.
		 * Later, the last cumulative sum of the reward amount is subtracted because to add the last recorded holder/staking reward.
		 */
		uint256 price =
			allStakes > 0 ? mReward.sub(lastReward).div(allStakes) : 0;

		/**
		 * Calculates the holders reward out of the total reward amount.
		 */
		uint256 holdersShare =
			IPolicy(config().policy()).holdersShare(price, allStakes);

		/**
		 * Calculates and returns each reward.
		 */
		uint256 holdersPrice = holdersShare.add(lastHoldersPrice);
		uint256 interestPrice = price.sub(holdersShare).add(lastInterestPrice);
		return (mReward, holdersPrice, interestPrice);
	}

	/**
	 * Calculates cumulative sum of the holders reward per Property.
	 * To save computing resources, it receives the latest holder rewards from a caller.
	 */
	function _calculateCumulativeHoldersRewardAmount(
		uint256 _reward,
		address _property
	) private view returns (uint256) {
		(uint256 cHoldersReward, uint256 lastReward) =
			(
				getStorageLastCumulativeHoldersRewardAmountPerProperty(
					_property
				),
				getStorageLastCumulativeHoldersRewardPricePerProperty(_property)
			);

		/**
		 * `cHoldersReward` contains the calculation of `lastReward`, so subtract it here.
		 */
		uint256 additionalHoldersReward =
			_reward.sub(lastReward).mul(getStoragePropertyValue(_property));

		/**
		 * Calculates and returns the cumulative sum of the holder reward by adds the last recorded holder reward and the latest holder reward.
		 */
		return cHoldersReward.add(additionalHoldersReward);
	}

	/**
	 * Calculates cumulative sum of the holders reward per Property.
	 */
	function calculateCumulativeHoldersRewardAmount(address _property)
		public
		view
		returns (uint256)
	{
		(, uint256 holders, ) = calculateCumulativeRewardPrices();
		return _calculateCumulativeHoldersRewardAmount(holders, _property);
	}

	/**
	 * Updates cumulative sum of the maximum mint amount calculated by Allocator contract, the latest maximum mint amount per block,
	 * and the last recorded block number.
	 * The cumulative sum of the maximum mint amount is always added.
	 * By recording that value when the staker last stakes, the difference from the when the staker stakes can be calculated.
	 */
	function update() public {
		/**
		 * Gets the cumulative sum of the maximum mint amount and the maximum mint number per block.
		 */
		(uint256 _nextRewards, uint256 _amount) = dry();

		/**
		 * Records each value and the latest block number.
		 */
		setStorageCumulativeGlobalRewards(_nextRewards);
		setStorageLastSameRewardsAmountAndBlock(_amount, block.number);
	}

	/**
	 * Referring to the values recorded in each storage to returns the latest cumulative sum of the maximum mint amount and the latest maximum mint amount per block.
	 */
	function dry()
		private
		view
		returns (uint256 _nextRewards, uint256 _amount)
	{
		/**
		 * Gets the latest mint amount per block from Allocator contract.
		 */
		uint256 rewardsAmount =
			IAllocator(config().allocator()).calculateMaxRewardsPerBlock();

		/**
		 * Gets the maximum mint amount per block, and the last recorded block number from `LastSameRewardsAmountAndBlock` storage.
		 */
		(uint256 lastAmount, uint256 lastBlock) =
			getStorageLastSameRewardsAmountAndBlock();

		/**
		 * If the recorded maximum mint amount per block and the result of the Allocator contract are different,
		 * the result of the Allocator contract takes precedence as a maximum mint amount per block.
		 */
		uint256 lastMaxRewards =
			lastAmount == rewardsAmount ? rewardsAmount : lastAmount;

		/**
		 * Calculates the difference between the latest block number and the last recorded block number.
		 */
		uint256 blocks = lastBlock > 0 ? block.number.sub(lastBlock) : 0;

		/**
		 * Adds the calculated new cumulative maximum mint amount to the recorded cumulative maximum mint amount.
		 */
		uint256 additionalRewards = lastMaxRewards.mul(blocks);
		uint256 nextRewards =
			getStorageCumulativeGlobalRewards().add(additionalRewards);

		/**
		 * Returns the latest theoretical cumulative sum of maximum mint amount and maximum mint amount per block.
		 */
		return (nextRewards, rewardsAmount);
	}

	/**
	 * Returns the staker reward as interest.
	 */
	function _calculateInterestAmount(address _property, address _user)
		private
		view
		returns (
			uint256 _amount,
			uint256 _interestPrice,
			RewardPrices memory _prices
		)
	{
		/**
		 * Get the amount the user is staking for the Property.
		 */
		uint256 lockedUpPerAccount = getStorageValue(_property, _user);

		/**
		 * Gets the cumulative sum of the interest price recorded the last time you withdrew.
		 */
		uint256 lastInterest =
			getStorageLastStakedInterestPrice(_property, _user);

		/**
		 * Gets the latest cumulative sum of the interest price.
		 */
		(uint256 reward, uint256 holders, uint256 interest) =
			calculateCumulativeRewardPrices();

		/**
		 * Calculates and returns the latest withdrawable reward amount from the difference.
		 */
		uint256 result =
			interest >= lastInterest
				? interest.sub(lastInterest).mul(lockedUpPerAccount).divBasis()
				: 0;
		return (result, interest, RewardPrices(reward, holders, interest));
	}

	/**
	 * Returns the total rewards currently available for withdrawal. (For calling from inside the contract)
	 */
	function _calculateWithdrawableInterestAmount(
		address _property,
		address _user
	) private view returns (uint256 _amount, RewardPrices memory _prices) {
		/**
		 * If the passed Property has not authenticated, returns always 0.
		 */
		if (
			IMetricsGroup(config().metricsGroup()).hasAssets(_property) == false
		) {
			return (0, RewardPrices(0, 0, 0));
		}

		/**
		 * Gets the reward amount in saved without withdrawal.
		 */
		uint256 pending = getStoragePendingInterestWithdrawal(_property, _user);

		/**
		 * Gets the reward amount of before DIP4.
		 */
		uint256 legacy = __legacyWithdrawableInterestAmount(_property, _user);

		/**
		 * Gets the latest withdrawal reward amount.
		 */
		(uint256 amount, , RewardPrices memory prices) =
			_calculateInterestAmount(_property, _user);

		/**
		 * Returns the sum of all values.
		 */
		uint256 withdrawableAmount = amount.add(pending).add(legacy);
		return (withdrawableAmount, prices);
	}

	/**
	 * Returns the total rewards currently available for withdrawal. (For calling from external of the contract)
	 */
	function calculateWithdrawableInterestAmount(
		address _property,
		address _user
	) public view returns (uint256) {
		(uint256 amount, ) =
			_calculateWithdrawableInterestAmount(_property, _user);
		return amount;
	}

	/**
	 * Withdraws staking reward as an interest.
	 */
	function _withdrawInterest(address _property)
		private
		returns (RewardPrices memory _prices)
	{
		/**
		 * Gets the withdrawable amount.
		 */
		(uint256 value, RewardPrices memory prices) =
			_calculateWithdrawableInterestAmount(_property, msg.sender);

		/**
		 * Sets the unwithdrawn reward amount to 0.
		 */
		setStoragePendingInterestWithdrawal(_property, msg.sender, 0);

		/**
		 * Updates the staking status to avoid double rewards.
		 */
		setStorageLastStakedInterestPrice(
			_property,
			msg.sender,
			prices.interest
		);
		__updateLegacyWithdrawableInterestAmount(_property, msg.sender);

		/**
		 * Mints the reward.
		 */
		require(
			IDevMinter(devMinter).mint(msg.sender, value),
			"dev mint failed"
		);

		/**
		 * Since the total supply of tokens has changed, updates the latest maximum mint amount.
		 */
		update();

		return prices;
	}

	/**
	 * Status updates with the addition or release of staking.
	 */
	function updateValues(
		bool _addition,
		address _account,
		address _property,
		uint256 _value,
		RewardPrices memory _prices
	) private {
		beforeStakesChanged(_property, _account, _prices);
		/**
		 * If added staking:
		 */
		if (_addition) {
			/**
			 * Updates the current staking amount of the protocol total.
			 */
			addAllValue(_value);

			/**
			 * Updates the current staking amount of the Property.
			 */
			addPropertyValue(_property, _value);

			/**
			 * Updates the user's current staking amount in the Property.
			 */
			addValue(_property, _account, _value);

			/**
			 * If released staking:
			 */
		} else {
			/**
			 * Updates the current staking amount of the protocol total.
			 */
			subAllValue(_value);

			/**
			 * Updates the current staking amount of the Property.
			 */
			subPropertyValue(_property, _value);

			/**
			 * Updates the current staking amount of the Property.
			 */
			subValue(_property, _account, _value);
		}

		/**
		 * Since each staking amount has changed, updates the latest maximum mint amount.
		 */
		update();
	}

	/**
	 * Returns the staking amount of the protocol total.
	 */
	function getAllValue() external view returns (uint256) {
		return getStorageAllValue();
	}

	/**
	 * Adds the staking amount of the protocol total.
	 */
	function addAllValue(uint256 _value) private {
		uint256 value = getStorageAllValue();
		value = value.add(_value);
		setStorageAllValue(value);
	}

	/**
	 * Subtracts the staking amount of the protocol total.
	 */
	function subAllValue(uint256 _value) private {
		uint256 value = getStorageAllValue();
		value = value.sub(_value);
		setStorageAllValue(value);
	}

	/**
	 * Returns the user's staking amount in the Property.
	 */
	function getValue(address _property, address _sender)
		external
		view
		returns (uint256)
	{
		return getStorageValue(_property, _sender);
	}

	/**
	 * Adds the user's staking amount in the Property.
	 */
	function addValue(
		address _property,
		address _sender,
		uint256 _value
	) private {
		uint256 value = getStorageValue(_property, _sender);
		value = value.add(_value);
		setStorageValue(_property, _sender, value);
	}

	/**
	 * Subtracts the user's staking amount in the Property.
	 */
	function subValue(
		address _property,
		address _sender,
		uint256 _value
	) private {
		uint256 value = getStorageValue(_property, _sender);
		value = value.sub(_value);
		setStorageValue(_property, _sender, value);
	}

	/**
	 * Returns whether the user is staking in the Property.
	 */
	function hasValue(
		address _property,
		address _sender,
		uint256 _amount
	) private view returns (bool) {
		uint256 value = getStorageValue(_property, _sender);
		return value >= _amount;
	}

	/**
	 * Returns the staking amount of the Property.
	 */
	function getPropertyValue(address _property)
		external
		view
		returns (uint256)
	{
		return getStoragePropertyValue(_property);
	}

	/**
	 * Adds the staking amount of the Property.
	 */
	function addPropertyValue(address _property, uint256 _value) private {
		uint256 value = getStoragePropertyValue(_property);
		value = value.add(_value);
		setStoragePropertyValue(_property, value);
	}

	/**
	 * Subtracts the staking amount of the Property.
	 */
	function subPropertyValue(address _property, uint256 _value) private {
		uint256 value = getStoragePropertyValue(_property);
		uint256 nextValue = value.sub(_value);
		setStoragePropertyValue(_property, nextValue);
	}

	/**
	 * Saves the latest reward amount as an undrawn amount.
	 */
	function updatePendingInterestWithdrawal(address _property, address _user)
		private
		returns (RewardPrices memory _prices)
	{
		/**
		 * Gets the latest reward amount.
		 */
		(uint256 withdrawableAmount, RewardPrices memory prices) =
			_calculateWithdrawableInterestAmount(_property, _user);

		/**
		 * Saves the amount to `PendingInterestWithdrawal` storage.
		 */
		setStoragePendingInterestWithdrawal(
			_property,
			_user,
			withdrawableAmount
		);

		/**
		 * Updates the reward amount of before DIP4 to prevent further addition it.
		 */
		__updateLegacyWithdrawableInterestAmount(_property, _user);

		return prices;
	}

	/**
	 * Returns the reward amount of the calculation model before DIP4.
	 * It can be calculated by subtracting "the last cumulative sum of reward unit price" from
	 * "the current cumulative sum of reward unit price," and multiplying by the staking amount.
	 */
	function __legacyWithdrawableInterestAmount(
		address _property,
		address _user
	) private view returns (uint256) {
		uint256 _last = getStorageLastInterestPrice(_property, _user);
		uint256 price = getStorageInterestPrice(_property);
		uint256 priceGap = price.sub(_last);
		uint256 lockedUpValue = getStorageValue(_property, _user);
		uint256 value = priceGap.mul(lockedUpValue);
		return value.divBasis();
	}

	/**
	 * Updates and treats the reward of before DIP4 as already received.
	 */
	function __updateLegacyWithdrawableInterestAmount(
		address _property,
		address _user
	) private {
		uint256 interestPrice = getStorageInterestPrice(_property);
		if (getStorageLastInterestPrice(_property, _user) != interestPrice) {
			setStorageLastInterestPrice(_property, _user, interestPrice);
		}
	}
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"_config","type":"address"},{"internalType":"address","name":"_devMinter","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_from","type":"address"},{"indexed":false,"internalType":"address","name":"_property","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Lockedup","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"constant":true,"inputs":[{"internalType":"address","name":"_property","type":"address"}],"name":"calculateCumulativeHoldersRewardAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"calculateCumulativeRewardPrices","outputs":[{"internalType":"uint256","name":"_reward","type":"uint256"},{"internalType":"uint256","name":"_holders","type":"uint256"},{"internalType":"uint256","name":"_interest","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_property","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"calculateWithdrawableInterestAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"changeOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"configAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"createStorage","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"devMinter","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getAllValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_property","type":"address"}],"name":"getPropertyValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getStorageAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getStorageAllValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getStorageCumulativeGlobalRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getStorageDIP4GenesisBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_property","type":"address"}],"name":"getStorageInterestPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_property","type":"address"}],"name":"getStorageLastCumulativeHoldersRewardAmountPerProperty","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getStorageLastCumulativeHoldersRewardPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_property","type":"address"}],"name":"getStorageLastCumulativeHoldersRewardPricePerProperty","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getStorageLastCumulativeInterestPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_property","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"getStorageLastInterestPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getStorageLastSameRewardsAmountAndBlock","outputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_block","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_property","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"getStorageLastStakedInterestPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getStorageLastStakesChangedCumulativeReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_property","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"getStoragePendingInterestWithdrawal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_property","type":"address"}],"name":"getStoragePropertyValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_property","type":"address"},{"internalType":"address","name":"_sender","type":"address"}],"name":"getStorageValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_property","type":"address"},{"internalType":"address","name":"_sender","type":"address"}],"name":"getValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_property","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"lockup","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_storageAddress","type":"address"}],"name":"setStorage","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"update","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_property","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b5060405162003555380380620035558339818101604052604081101561003557600080fd5b508051602090910151600080546001600160a01b0319166001600160a01b0384161781556100616100d5565b600180546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600380546001600160a01b0319166001600160a01b0392909216919091179055506100d9565b3390565b61346c80620000e96000396000f3fe608060405234801561001057600080fd5b50600436106102065760003560e01c80639137c1a71161011a578063d6c31871116100ad578063f2fde38b1161007c578063f2fde38b1461052c578063f3fef3a314610552578063f9c514e41461057e578063fb971d01146105ac578063fd1ac3d8146105b457610206565b8063d6c31871146104a7578063e35e8cf1146104af578063edaf329f146104e5578063eebf29361461050657610206565b8063a6f9dae1116100e9578063a6f9dae11461042d578063af61a9c514610453578063c311c53614610479578063c7ab3a221461048157610206565b80639137c1a7146103c957806394ab898c146103ef57806395490d6c146103f7578063a2e620451461042557610206565b80636afa639c1161019d5780638017333d1161016c5780638017333d1461036f57806381136f5a1461037757806387407e4c1461039d5780638da5cb5b146103a55780638f32d59b146103ad57610206565b80636afa639c14610327578063714d695814610355578063715018a61461035d5780637654f7ab1461036757610206565b8063523f91b6116101d9578063523f91b61461029d57806355fac3be146102c3578063603da01d146102f157806360cec3701461031f57610206565b8063076ae4771461020b5780630c71c3e814610243578063270d33bc1461024b578063393a4d3414610279575b600080fd5b6102316004803603602081101561022157600080fd5b50356001600160a01b03166105da565b60408051918252519081900360200190f35b610231610661565b6102316004803603604081101561026157600080fd5b506001600160a01b03813581169160200135166106e6565b610281610771565b604080516001600160a01b039092168252519081900360200190f35b610231600480360360208110156102b357600080fd5b50356001600160a01b03166107d6565b610231600480360360408110156102d957600080fd5b506001600160a01b03813581169160200135166107f7565b6102316004803603604081101561030757600080fd5b506001600160a01b038135811691602001351661080a565b61023161082c565b6102316004803603604081101561033d57600080fd5b506001600160a01b038135811691602001351661084c565b61023161086e565b61036561088e565b005b61023161091f565b61023161092e565b6102316004803603602081101561038d57600080fd5b50356001600160a01b031661094e565b6102316109da565b610281610a64565b6103b5610a73565b604080519115158252519081900360200190f35b610365600480360360208110156103df57600080fd5b50356001600160a01b0316610a99565b610281610b02565b6102316004803603604081101561040d57600080fd5b506001600160a01b0381358116916020013516610b11565b610365610b9f565b6103656004803603602081101561044357600080fd5b50356001600160a01b0316610bc5565b61045b610c75565b60408051938452602084019290925282820152519081900360600190f35b610231610e2b565b6102316004803603602081101561049757600080fd5b50356001600160a01b0316610e4b565b610281610e6c565b610365600480360360608110156104c557600080fd5b506001600160a01b03813581169160208101359091169060400135610e7b565b6104ed61111b565b6040805192835260208301919091528051918290030190f35b6102316004803603602081101561051c57600080fd5b50356001600160a01b03166111fe565b6103656004803603602081101561054257600080fd5b50356001600160a01b0316611217565b6103656004803603604081101561056857600080fd5b506001600160a01b03813516906020013561126a565b6102316004803603604081101561059457600080fd5b506001600160a01b0381358116916020013516611359565b61036561136f565b610231600480360360208110156105ca57600080fd5b50356001600160a01b0316611453565b60006105e4610771565b6001600160a01b031663bd02d0f56105fb8461145e565b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561062f57600080fd5b505afa158015610643573d6000803e3d6000fd5b505050506040513d602081101561065957600080fd5b505192915050565b600061066b610771565b6001600160a01b031663bd02d0f56106816114ae565b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156106b557600080fd5b505afa1580156106c9573d6000803e3d6000fd5b505050506040513d60208110156106df57600080fd5b5051905090565b60006106f0610771565b6001600160a01b031663bd02d0f561070885856114df565b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561073c57600080fd5b505afa158015610750573d6000803e3d6000fd5b505050506040513d602081101561076657600080fd5b505190505b92915050565b6002546000906001600160a01b03166107c6576040805162461bcd60e51b81526020600482015260126024820152711cdd1bdc9859d9481a5cc81b9bdd081cd95d60721b604482015290519081900360640190fd5b506002546001600160a01b031690565b60006107e0610771565b6001600160a01b031663bd02d0f56105fb84611548565b60006108038383610b11565b9392505050565b6000610814610771565b6001600160a01b031663bd02d0f56107088585611597565b6000610836610771565b6001600160a01b031663bd02d0f56106816115fa565b6000610856610771565b6001600160a01b031663bd02d0f56107088585611636565b6000610878610771565b6001600160a01b031663bd02d0f5610681611698565b610896610a73565b6108d5576040805162461bcd60e51b815260206004820181905260248201526000805160206133ed833981519152604482015290519081900360640190fd5b6001546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600180546001600160a01b0319169055565b60006109296109da565b905090565b6000610938610771565b6001600160a01b031663bd02d0f56106816116e0565b60008061095a83611728565b9050610964610771565b6001600160a01b031663bd02d0f5826040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156109a757600080fd5b505afa1580156109bb573d6000803e3d6000fd5b505050506040513d60208110156109d157600080fd5b50519392505050565b6000806109e5611776565b90506109ef610771565b6001600160a01b031663bd02d0f5826040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610a3257600080fd5b505afa158015610a46573d6000803e3d6000fd5b505050506040513d6020811015610a5c57600080fd5b505191505090565b6001546001600160a01b031690565b6001546000906001600160a01b0316610a8a6117aa565b6001600160a01b031614905090565b610aa1610a73565b610ae0576040805162461bcd60e51b815260206004820181905260248201526000805160206133ed833981519152604482015290519081900360640190fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6003546001600160a01b031681565b600080610b1e84846117ae565b9050610b28610771565b6001600160a01b031663bd02d0f5826040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610b6b57600080fd5b505afa158015610b7f573d6000803e3d6000fd5b505050506040513d6020811015610b9557600080fd5b5051949350505050565b600080610baa611800565b91509150610bb782611956565b610bc181436119b2565b5050565b610bcd610a73565b610c0c576040805162461bcd60e51b815260206004820181905260248201526000805160206133ed833981519152604482015290519081900360640190fd5b6002546040805163a6f9dae160e01b81526001600160a01b0384811660048301529151919092169163a6f9dae191602480830192600092919082900301818387803b158015610c5a57600080fd5b505af1158015610c6e573d6000803e3d6000fd5b5050505050565b600080600080610c83610661565b90506000610c8f610e2b565b90506000610c9b61086e565b90506000610ca76109da565b90506000610cb3611800565b5090506000610cc182611a51565b90506000808411610cd3576000610cf3565b610cf384610ce7848a63ffffffff611a6b16565b9063ffffffff611aad16565b90506000610cff610e6c565b6001600160a01b0316630505c8c96040518163ffffffff1660e01b815260040160206040518083038186803b158015610d3757600080fd5b505afa158015610d4b573d6000803e3d6000fd5b505050506040513d6020811015610d6157600080fd5b505160408051631759a88560e31b8152600481018590526024810188905290516001600160a01b039092169163bacd442891604480820192602092909190829003018186803b158015610db357600080fd5b505afa158015610dc7573d6000803e3d6000fd5b505050506040513d6020811015610ddd57600080fd5b505190506000610df3828963ffffffff611aef16565b90506000610e1788610e0b868663ffffffff611a6b16565b9063ffffffff611aef16565b949d919c50939a5098505050505050505050565b6000610e35610771565b6001600160a01b031663bd02d0f5610681611b49565b6000610e55610771565b6001600160a01b031663bd02d0f56105fb84611b7a565b6000546001600160a01b031690565b610e83610e6c565b6001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015610ebb57600080fd5b505afa158015610ecf573d6000803e3d6000fd5b505050506040513d6020811015610ee557600080fd5b50516001600160a01b03163314610f43576040805162461bcd60e51b815260206004820152601760248201527f7468697320697320696c6c6567616c2061646472657373000000000000000000604482015290519081900360640190fd5b80610f8c576040805162461bcd60e51b8152602060048201526014602482015273696c6c6567616c206c6f636b75702076616c756560601b604482015290519081900360640190fd5b610f94610e6c565b6001600160a01b031663628f043d6040518163ffffffff1660e01b815260040160206040518083038186803b158015610fcc57600080fd5b505afa158015610fe0573d6000803e3d6000fd5b505050506040513d6020811015610ff657600080fd5b505160408051638b234cb160e01b81526001600160a01b03858116600483015291519190921691638b234cb1916024808301926020929190829003018186803b15801561104257600080fd5b505afa158015611056573d6000803e3d6000fd5b505050506040513d602081101561106c57600080fd5b50516110a95760405162461bcd60e51b815260040180806020018281038252602b81526020018061340d602b913960400191505060405180910390fd5b6110b16126b1565b6110bb8385611bca565b90506110cb600185858585611c07565b604080516001600160a01b0380871682528516602082015280820184905290517f71601c75cd9722fdbd6d57dbb30980d4a4bd6169ba3d456dc18b7f878629d7bf9181900360600190a150505050565b6000806000611128610771565b6001600160a01b031663bd02d0f561113e611c61565b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561117257600080fd5b505afa158015611186573d6000803e3d6000fd5b505050506040513d602081101561119c57600080fd5b5051905060006111c0826d04ee2d6d415b85acef810000000063ffffffff611aad16565b905060006111f26111e5836d04ee2d6d415b85acef810000000063ffffffff611ca916565b849063ffffffff611a6b16565b91945090925050509091565b600080611209610c75565b509150506108038184611d02565b61121f610a73565b61125e576040805162461bcd60e51b815260206004820181905260248201526000805160206133ed833981519152604482015290519081900360640190fd5b61126781611d63565b50565b611275823383611e04565b6112c6576040805162461bcd60e51b815260206004820152601a60248201527f696e73756666696369656e7420746f6b656e73207374616b6564000000000000604482015290519081900360640190fd5b6112ce6126b1565b6112d783611e1d565b90508115611346576040805163f3fef3a360e01b81523360048201526024810184905290516001600160a01b0385169163f3fef3a391604480830192600092919082900301818387803b15801561132d57600080fd5b505af1158015611341573d6000803e3d6000fd5b505050505b611354600033858585611c07565b505050565b6000806113668484611f2d565b50949350505050565b611377610a73565b6113b6576040805162461bcd60e51b815260206004820181905260248201526000805160206133ed833981519152604482015290519081900360640190fd5b6002546001600160a01b031615611405576040805162461bcd60e51b815260206004820152600e60248201526d1cdd1bdc9859d9481a5cc81cd95d60921b604482015290519081900360640190fd5b6000604051611413906126d2565b604051809103906000f08015801561142f573d6000803e3d6000fd5b50600280546001600160a01b0319166001600160a01b039290921691909117905550565b600061076b8261094e565b600081604051602001808061330a602d9139602d01826001600160a01b03166001600160a01b031660601b8152601401915050604051602081830303815290604052805190602001209050919050565b6000604051602001808061337e60229139602201905060405160208183030381529060405280519060200120905090565b604080517f5f70656e64696e67496e7465726573745769746864726177616c0000000000006020808301919091526001600160601b0319606086811b8216603a85015285901b16604e830152825160428184030181526062909201909252805191012092915050565b604080516e5f696e746572657374546f74616c7360881b60208083019190915260609390931b6001600160601b031916602f820152815180820360230181526043909101909152805191012090565b604080517f5f6c6173745374616b6564496e746572657374507269636500000000000000006020808301919091526001600160601b0319606095861b8116603884015293851b909316604c82015281518082038301815293019052815191012090565b60408051705f6469703447656e65736973426c6f636b60781b602080830191909152825180830360110181526031909201909252805191012090565b60408051755f6c6173744c617374496e746572657374507269636560501b6020808301919091526001600160601b0319606086811b8216603685015285901b16604a8301528251603e818403018152605e909201909252805191012092915050565b604080517f306c61737443756d756c6174697665496e7465726573745072696365000000006020808301919091528251808303601c018152603c909201909252805191012090565b604080517f5f63756d756c6174697665476c6f62616c526577617264730000000000000000602080830191909152825180830360180181526038909201909252805191012090565b604080516d5f70726f706572747956616c756560901b60208083019190915260609390931b6001600160601b031916602e820152815180820360220181526042909101909152805191012090565b60408051685f616c6c56616c756560b81b602080830191909152825180830360090181526029909201909252805191012090565b3390565b60408051655f76616c756560d01b6020808301919091526001600160601b0319606086811b8216602685015285901b16603a8301528251602e818403018152604e909201909252805191012092915050565b600080600061180d610e6c565b6001600160a01b031663aa5dcecc6040518163ffffffff1660e01b815260040160206040518083038186803b15801561184557600080fd5b505afa158015611859573d6000803e3d6000fd5b505050506040513d602081101561186f57600080fd5b505160408051633aa5460b60e01b815290516001600160a01b0390921691633aa5460b91600480820192602092909190829003018186803b1580156118b357600080fd5b505afa1580156118c7573d6000803e3d6000fd5b505050506040513d60208110156118dd57600080fd5b505190506000806118ec61111b565b9150915060008383146118ff5782611901565b835b90506000808311611913576000611923565b611923438463ffffffff611a6b16565b90506000611937838363ffffffff611ca916565b9050600061194782610e0b61092e565b98509596505050505050509091565b61195e610771565b6001600160a01b031663e2a4853a6119746116e0565b836040518363ffffffff1660e01b81526004018083815260200182815260200192505050600060405180830381600087803b158015610c5a57600080fd5b60006119d682610e0b856d04ee2d6d415b85acef810000000063ffffffff611ca916565b90506119e0610771565b6001600160a01b031663e2a4853a6119f6611c61565b836040518363ffffffff1660e01b81526004018083815260200182815260200192505050600060405180830381600087803b158015611a3457600080fd5b505af1158015611a48573d6000803e3d6000fd5b50505050505050565b600061076b82670de0b6b3a764000063ffffffff611ca916565b600061080383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061209f565b600061080383836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612136565b600082820183811015610803576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000604051602001808061335d60219139602101905060405160208183030381529060405280519060200120905090565b60008160405160200180806133a0602c9139602c01826001600160a01b03166001600160a01b031660601b8152601401915050604051602081830303815290604052805190602001209050919050565b611bd26126b1565b6000611bdc6126b1565b611be68585611f2d565b91509150611bf585858461219b565b611bff85856121bb565b949350505050565b611c128385836121e3565b8415611c3b57611c2182612247565b611c2b838361226e565b611c36838584612297565b611c59565b611c44826122c2565b611c4e83836122de565b611c59838584612309565b610c6e610b9f565b604080517f5f4c61737453616d6552657761726473416d6f756e74416e64426c6f636b00006020808301919091528251808303601e018152603e909201909252805191012090565b600082611cb85750600061076b565b82820282848281611cc557fe5b04146108035760405162461bcd60e51b81526004018080602001828103825260218152602001806133cc6021913960400191505060405180910390fd5b6000806000611d10846105da565b611d1985610e4b565b915091506000611d47611d2b8661094e565b611d3b888563ffffffff611a6b16565b9063ffffffff611ca916565b9050611d59838263ffffffff611aef16565b9695505050505050565b6001600160a01b038116611da85760405162461bcd60e51b81526004018080602001828103825260268152602001806133376026913960400191505060405180910390fd5b6001546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b600080611e118585610b11565b90921115949350505050565b611e256126b1565b6000611e2f6126b1565b611e398433611f2d565b91509150611e498433600061219b565b611e5884338360400151612327565b611e6284336121bb565b600354604080516340c10f1960e01b81523360048201526024810185905290516001600160a01b03909216916340c10f19916044808201926020929091908290030181600087803b158015611eb657600080fd5b505af1158015611eca573d6000803e3d6000fd5b505050506040513d6020811015611ee057600080fd5b5051611f25576040805162461bcd60e51b815260206004820152600f60248201526e19195d881b5a5b9d0819985a5b1959608a1b604482015290519081900360640190fd5b610803610b9f565b6000611f376126b1565b611f3f610e6c565b6001600160a01b031663628f043d6040518163ffffffff1660e01b815260040160206040518083038186803b158015611f7757600080fd5b505afa158015611f8b573d6000803e3d6000fd5b505050506040513d6020811015611fa157600080fd5b505160408051638b234cb160e01b81526001600160a01b03878116600483015291519190921691638b234cb1916024808301926020929190829003018186803b158015611fed57600080fd5b505afa158015612001573d6000803e3d6000fd5b505050506040513d602081101561201757600080fd5b505161204057505060408051606081018252600080825260208201819052918101829052612098565b600061204c85856106e6565b9050600061205a8686612347565b905060006120666126b1565b61207088886123ae565b9250509150600061208e84610e0b8786611aef90919063ffffffff16565b9650909450505050505b9250929050565b6000818484111561212e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156120f35781810151838201526020016120db565b50505050905090810190601f1680156121205780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836121855760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156120f35781810151838201526020016120db565b50600083858161219157fe5b0495945050505050565b6121a3610771565b6001600160a01b031663e2a4853a6119f685856114df565b60006121c6836107d6565b9050806121d3848461084c565b1461135457611354838383612441565b60006121f3826020015185611d02565b905061220484848460400151612327565b815161220f90612461565b61221c826020015161247f565b612229826040015161249d565b61223384826124bb565b612241848360200151612534565b50505050565b60006122516109da565b9050612263818363ffffffff611aef16565b9050610bc181612553565b60006122798361094e565b905061228b818363ffffffff611aef16565b905061135483826125b4565b60006122a38484610b11565b90506122b5818363ffffffff611aef16565b9050612241848483612616565b60006122cc6109da565b9050612263818363ffffffff611a6b16565b60006122e98361094e565b905060006122fd828463ffffffff611a6b16565b905061224184826125b4565b60006123158484610b11565b90506122b5818363ffffffff611a6b16565b61232f610771565b6001600160a01b031663e2a4853a6119f68585611597565b600080612354848461084c565b90506000612361856107d6565b90506000612375828463ffffffff611a6b16565b905060006123838787610b11565b90506000612397838363ffffffff611ca916565b90506123a281612697565b98975050505050505050565b6000806123b96126b1565b60006123c58686610b11565b905060006123d3878761080a565b905060008060006123e2610c75565b9250925092506000848210156123f9576000612415565b61241561241087611d3b858963ffffffff611a6b16565b612697565b604080516060810182529586526020860194909452928401829052509096509450925050509250925092565b612449610771565b6001600160a01b031663e2a4853a6119f68585611636565b612469610771565b6001600160a01b031663e2a4853a6119746114ae565b612487610771565b6001600160a01b031663e2a4853a611974611b49565b6124a5610771565b6001600160a01b031663e2a4853a611974611698565b6124c3610771565b6001600160a01b031663e2a4853a6124da8461145e565b836040518363ffffffff1660e01b81526004018083815260200182815260200192505050600060405180830381600087803b15801561251857600080fd5b505af115801561252c573d6000803e3d6000fd5b505050505050565b61253c610771565b6001600160a01b031663e2a4853a6124da84611b7a565b600061255d611776565b9050612567610771565b6001600160a01b031663e2a4853a82846040518363ffffffff1660e01b81526004018083815260200182815260200192505050600060405180830381600087803b15801561251857600080fd5b60006125bf83611728565b90506125c9610771565b6001600160a01b031663e2a4853a82846040518363ffffffff1660e01b81526004018083815260200182815260200192505050600060405180830381600087803b158015611a3457600080fd5b600061262284846117ae565b905061262c610771565b6001600160a01b031663e2a4853a82846040518363ffffffff1660e01b81526004018083815260200182815260200192505050600060405180830381600087803b15801561267957600080fd5b505af115801561268d573d6000803e3d6000fd5b5050505050505050565b600061076b82670de0b6b3a764000063ffffffff611aad16565b60405180606001604052806000815260200160008152602001600081525090565b610c2a806126e08339019056fe6080604052600080546001600160a01b0319163317905534801561002257600080fd5b50610bf8806100326000396000f3fe608060405234801561001057600080fd5b50600436106101215760003560e01c8063a6f9dae1116100ad578063d5d2c56011610071578063d5d2c560146103f5578063dc97d96214610418578063e2a4853a14610435578063e2b202bf14610458578063f6bb3cc41461047557610121565b8063a6f9dae114610332578063abfdcced14610358578063bd02d0f51461037d578063c031a180146103ac578063ca446dd9146103c957610121565b8063616b59f6116100f4578063616b59f6146101be5780636e899550146101db5780637ae1cfca146102525780638c16009514610283578063986e791a146102a057610121565b80630e14a3761461012657806321f8a721146101455780632c62ff2d1461017e5780633e49bed01461019b575b600080fd5b6101436004803603602081101561013c57600080fd5b5035610492565b005b6101626004803603602081101561015b57600080fd5b50356104fd565b604080516001600160a01b039092168252519081900360200190f35b6101436004803603602081101561019457600080fd5b5035610518565b610143600480360360408110156101b157600080fd5b508035906020013561057d565b610143600480360360208110156101d457600080fd5b50356105dc565b610143600480360360408110156101f157600080fd5b8135919081019060408101602082013564010000000081111561021357600080fd5b82018360208201111561022557600080fd5b8035906020019184600183028401116401000000008311171561024757600080fd5b50909250905061063a565b61026f6004803603602081101561026857600080fd5b50356106a6565b604080519115158252519081900360200190f35b6101436004803603602081101561029957600080fd5b50356106bb565b6102bd600480360360208110156102b657600080fd5b5035610719565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102f75781810151838201526020016102df565b50505050905090810190601f1680156103245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101436004803603602081101561034857600080fd5b50356001600160a01b03166107b8565b6101436004803603604081101561036e57600080fd5b50803590602001351515610827565b61039a6004803603602081101561039357600080fd5b5035610894565b60408051918252519081900360200190f35b61039a600480360360208110156103c257600080fd5b50356108a6565b610143600480360360408110156103df57600080fd5b50803590602001356001600160a01b03166108b8565b6101436004803603604081101561040b57600080fd5b5080359060200135610933565b61039a6004803603602081101561042e57600080fd5b5035610992565b6101436004803603604081101561044b57600080fd5b50803590602001356109a4565b6101436004803603602081101561046e57600080fd5b5035610a03565b6101436004803603602081101561048b57600080fd5b5035610a61565b6000546001600160a01b031633146104df576040805162461bcd60e51b81526020600482015260116024820152600080516020610ba4833981519152604482015290519081900360640190fd5b600090815260036020526040902080546001600160a01b0319169055565b6000908152600360205260409020546001600160a01b031690565b6000546001600160a01b03163314610565576040805162461bcd60e51b81526020600482015260116024820152600080516020610ba4833981519152604482015290519081900360640190fd5b6000908152600560205260409020805460ff19169055565b6000546001600160a01b031633146105ca576040805162461bcd60e51b81526020600482015260116024820152600080516020610ba4833981519152604482015290519081900360640190fd5b60009182526006602052604090912055565b6000546001600160a01b03163314610629576040805162461bcd60e51b81526020600482015260116024820152600080516020610ba4833981519152604482015290519081900360640190fd5b600090815260046020526040812055565b6000546001600160a01b03163314610687576040805162461bcd60e51b81526020600482015260116024820152600080516020610ba4833981519152604482015290519081900360640190fd5b60008381526002602052604090206106a0908383610ac8565b50505050565b60009081526005602052604090205460ff1690565b6000546001600160a01b03163314610708576040805162461bcd60e51b81526020600482015260116024820152600080516020610ba4833981519152604482015290519081900360640190fd5b600090815260066020526040812055565b600081815260026020818152604092839020805484516001821615610100026000190190911693909304601f810183900483028401830190945283835260609390918301828280156107ac5780601f10610781576101008083540402835291602001916107ac565b820191906000526020600020905b81548152906001019060200180831161078f57829003601f168201915b50505050509050919050565b6000546001600160a01b03163314610805576040805162461bcd60e51b81526020600482015260116024820152600080516020610ba4833981519152604482015290519081900360640190fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b03163314610874576040805162461bcd60e51b81526020600482015260116024820152600080516020610ba4833981519152604482015290519081900360640190fd5b600091825260056020526040909120805460ff1916911515919091179055565b60009081526001602052604090205490565b60009081526004602052604090205490565b6000546001600160a01b03163314610905576040805162461bcd60e51b81526020600482015260116024820152600080516020610ba4833981519152604482015290519081900360640190fd5b60009182526003602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b6000546001600160a01b03163314610980576040805162461bcd60e51b81526020600482015260116024820152600080516020610ba4833981519152604482015290519081900360640190fd5b60009182526004602052604090912055565b60009081526006602052604090205490565b6000546001600160a01b031633146109f1576040805162461bcd60e51b81526020600482015260116024820152600080516020610ba4833981519152604482015290519081900360640190fd5b60009182526001602052604090912055565b6000546001600160a01b03163314610a50576040805162461bcd60e51b81526020600482015260116024820152600080516020610ba4833981519152604482015290519081900360640190fd5b600090815260016020526040812055565b6000546001600160a01b03163314610aae576040805162461bcd60e51b81526020600482015260116024820152600080516020610ba4833981519152604482015290519081900360640190fd5b6000818152600260205260408120610ac591610b46565b50565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610b095782800160ff19823516178555610b36565b82800160010185558215610b36579182015b82811115610b36578235825591602001919060010190610b1b565b50610b42929150610b86565b5090565b50805460018160011615610100020316600290046000825580601f10610b6c5750610ac5565b601f016020900490600052602060002090810190610ac591905b610ba091905b80821115610b425760008155600101610b8c565b9056fe6e6f742063757272656e74206f776e6572000000000000000000000000000000a265627a7a7231582057b8f79d63d7401460f294f799b49ede95894ae9e0caba7b38d88fb5d7c66fd364736f6c63430005110032306c61737443756d756c6174697665486f6c64657273526577617264416d6f756e7450657250726f70657274794f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373306c61737443756d756c6174697665486f6c6465727352657761726450726963655f6c6173745374616b65734368616e67656443756d756c6174697665526577617264306c61737443756d756c6174697665486f6c64657273526577617264507269636550657250726f7065727479536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572756e61626c6520746f207374616b6520746f20756e61757468656e746963617465642070726f7065727479a265627a7a72315820d47666347b6303bc0919f6de2d0a3784ecb78f938d3c7b790935a7f2e560fd1a64736f6c63430005110032000000000000000000000000d6d07f1c048bdf2b3d5d9b6c25ed1fc5348d0a70000000000000000000000000d9699cc995e8a5853eb1fa70b2f9e87eb7fa6a7a

Deployed ByteCode Sourcemap

35823:17338:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;35823:17338:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29241:259;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;29241:259:0;-1:-1:-1;;;;;29241:259:0;;:::i;:::-;;;;;;;;;;;;;;;;27329:202;;;:::i;25449:233::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;25449:233:0;;;;;;;;;;:::i;19721:97::-;;;:::i;:::-;;;;-1:-1:-1;;;;;19721:97:0;;;;;;;;;;;;;;22793:173;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;22793:173:0;-1:-1:-1;;;;;22793:173:0;;:::i;49535:149::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;49535:149:0;;;;;;;;;;:::i;26632:230::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;26632:230:0;;;;;;;;;;:::i;26084:142::-;;;:::i;23388:218::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;23388:218:0;;;;;;;;;;:::i;28563:190::-;;;:::i;13277:140::-;;;:::i;:::-;;48925:92;;;:::i;24864:156::-;;;:::i;22153:195::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;22153:195:0;-1:-1:-1;;;;;22153:195:0;;:::i;21053:148::-;;;:::i;12466:79::-;;;:::i;12832:94::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;20314:100;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;20314:100:0;-1:-1:-1;;;;;20314:100:0;;:::i;35942:24::-;;;:::i;21550:205::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;21550:205:0;;;;;;;;;;:::i;42148:381::-;;;:::i;20543:114::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;20543:114:0;-1:-1:-1;;;;;20543:114:0;;:::i;39249:1250::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;27959:200;;;:::i;30066:257::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;30066:257:0;-1:-1:-1;;;;;30066:257:0;;:::i;9863:81::-;;;:::i;36422:985::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;36422:985:0;;;;;;;;;;;;;;;;;:::i;24128:356::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;41521:246;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;41521:246:0;-1:-1:-1;;;;;41521:246:0;;:::i;13572:109::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;13572:109:0;-1:-1:-1;;;;;13572:109:0;;:::i;37555:654::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;37555:654:0;;;;;;;;:::i;46443:226::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;46443:226:0;;;;;;;;;;:::i;20001:177::-;;;:::i;50629:139::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;50629:139:0;-1:-1:-1;;;;;50629:139:0;;:::i;29241:259::-;29352:7;29377:16;:14;:16::i;:::-;-1:-1:-1;;;;;29377:24:0;;29408:81;29473:9;29408:57;:81::i;:::-;29377:118;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;29377:118:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;29377:118:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;29377:118:0;;29241:259;-1:-1:-1;;29241:259:0:o;27329:202::-;27414:7;27441:16;:14;:16::i;:::-;-1:-1:-1;;;;;27441:24:0;;27472:48;:46;:48::i;:::-;27441:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;27441:85:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;27441:85:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;27441:85:0;;-1:-1:-1;27329:202:0;:::o;25449:233::-;25559:7;25584:16;:14;:16::i;:::-;-1:-1:-1;;;;;25584:24:0;;25615:56;25654:9;25665:5;25615:38;:56::i;:::-;25584:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;25584:93:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;25584:93:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;25584:93:0;;-1:-1:-1;25449:233:0;;;;;:::o;19721:97::-;19409:8;;19784:7;;-1:-1:-1;;;;;19409:8:0;19401:53;;;;;-1:-1:-1;;;19401:53:0;;;;;;;;;;;;-1:-1:-1;;;19401:53:0;;;;;;;;;;;;;;;-1:-1:-1;19805:8:0;;-1:-1:-1;;;;;19805:8:0;19721:97;:::o;22793:173::-;22875:7;22898:16;:14;:16::i;:::-;-1:-1:-1;;;;;22898:24:0;;22923:37;22950:9;22923:26;:37::i;49535:149::-;49621:7;49644:35;49660:9;49671:7;49644:15;:35::i;:::-;49637:42;49535:149;-1:-1:-1;;;49535:149:0:o;26632:230::-;26739:7;26766:16;:14;:16::i;:::-;-1:-1:-1;;;;;26766:24:0;;26797:54;26834:9;26845:5;26797:36;:54::i;26084:142::-;26143:7;26164:16;:14;:16::i;:::-;-1:-1:-1;;;;;26164:24:0;;26189:31;:29;:31::i;23388:218::-;23489:7;23516:16;:14;:16::i;:::-;-1:-1:-1;;;;;23516:24:0;;23547:48;23578:9;23589:5;23547:30;:48::i;28563:190::-;28642:7;28669:16;:14;:16::i;:::-;-1:-1:-1;;;;;28669:24:0;;28700:42;:40;:42::i;13277:140::-;12678:9;:7;:9::i;:::-;12670:54;;;;;-1:-1:-1;;;12670:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;12670:54:0;;;;;;;;;;;;;;;13360:6;;13339:40;;13376:1;;-1:-1:-1;;;;;13360:6:0;;13339:40;;13376:1;;13339:40;13390:6;:19;;-1:-1:-1;;;;;;13390:19:0;;;13277:140::o;48925:92::-;48971:7;48992:20;:18;:20::i;:::-;48985:27;;48925:92;:::o;24864:156::-;24930:7;24951:16;:14;:16::i;:::-;-1:-1:-1;;;;;24951:24:0;;24976:38;:36;:38::i;22153:195::-;22235:7;22251:11;22265:37;22292:9;22265:26;:37::i;:::-;22251:51;;22314:16;:14;:16::i;:::-;-1:-1:-1;;;;;22314:24:0;;22339:3;22314:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;22314:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;22314:29:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;22314:29:0;;22153:195;-1:-1:-1;;;22153:195:0:o;21053:148::-;21104:7;21118:11;21132:23;:21;:23::i;:::-;21118:37;;21167:16;:14;:16::i;:::-;-1:-1:-1;;;;;21167:24:0;;21192:3;21167:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;21167:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;21167:29:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21167:29:0;;-1:-1:-1;;21053:148:0;:::o;12466:79::-;12531:6;;-1:-1:-1;;;;;12531:6:0;12466:79;:::o;12832:94::-;12912:6;;12872:4;;-1:-1:-1;;;;;12912:6:0;12896:12;:10;:12::i;:::-;-1:-1:-1;;;;;12896:22:0;;12889:29;;12832:94;:::o;20314:100::-;12678:9;:7;:9::i;:::-;12670:54;;;;;-1:-1:-1;;;12670:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;12670:54:0;;;;;;;;;;;;;;;20383:8;:26;;-1:-1:-1;;;;;;20383:26:0;-1:-1:-1;;;;;20383:26:0;;;;;;;;;;20314:100::o;35942:24::-;;;-1:-1:-1;;;;;35942:24:0;;:::o;21550:205::-;21641:7;21657:11;21671:38;21690:9;21701:7;21671:18;:38::i;:::-;21657:52;;21721:16;:14;:16::i;:::-;-1:-1:-1;;;;;21721:24:0;;21746:3;21721:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;21721:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;21721:29:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21721:29:0;;21550:205;-1:-1:-1;;;;21550:205:0:o;42148:381::-;42289:20;42311:15;42330:5;:3;:5::i;:::-;42288:47;;;;42410;42444:12;42410:33;:47::i;:::-;42462:62;42502:7;42511:12;42462:39;:62::i;:::-;42148:381;;:::o;20543:114::-;12678:9;:7;:9::i;:::-;12670:54;;;;;-1:-1:-1;;;12670:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;12670:54:0;;;;;;;;;;;;;;;20621:8;;20606:46;;;-1:-1:-1;;;20606:46:0;;-1:-1:-1;;;;;20606:46:0;;;;;;;;;20621:8;;;;;20606:36;;:46;;;;;20621:8;;20606:46;;;;;;;20621:8;;20606:46;;;5:2:-1;;;;30:1;27;20:12;5:2;20606:46:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;20606:46:0;;;;20543:114;:::o;39249:1250::-;39327:15;39348:16;39370:17;39400:18;39421:45;:43;:45::i;:::-;39400:66;;39471:24;39498:44;:42;:44::i;:::-;39471:71;;39547:25;39575:39;:37;:39::i;:::-;39547:67;;39619:17;39639:20;:18;:20::i;:::-;39619:40;;39736:14;39756:5;:3;:5::i;:::-;39735:26;;;39766:15;39784:17;:6;:15;:17::i;:::-;39766:35;;39998:13;40030:1;40018:9;:13;:58;;40075:1;40018:58;;;40034:38;40062:9;40034:23;:7;40046:10;40034:23;:11;:23;:::i;:::-;:27;:38;:27;:38;:::i;:::-;39998:78;;40165:20;40200:8;:6;:8::i;:::-;-1:-1:-1;;;;;40200:15:0;;:17;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40200:17:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;40200:17:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;40200:17:0;40192:57;;;-1:-1:-1;;;40192:57:0;;;;;;;;;;;;;;;;-1:-1:-1;;;;;40192:39:0;;;;;;:57;;;;;40200:17;;40192:57;;;;;;;;:39;:57;;;5:2:-1;;;;30:1;27;20:12;5:2;40192:57:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;40192:57:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;40192:57:0;;-1:-1:-1;40312:20:0;40335:34;40192:57;40352:16;40335:34;:16;:34;:::i;:::-;40312:57;-1:-1:-1;40374:21:0;40398:46;40426:17;40398:23;:5;40408:12;40398:23;:9;:23;:::i;:::-;:27;:46;:27;:46;:::i;:::-;40457:7;;40466:12;;-1:-1:-1;40457:7:0;;-1:-1:-1;39249:1250:0;-1:-1:-1;;;;;;;;;39249:1250:0:o;27959:200::-;28043:7;28070:16;:14;:16::i;:::-;-1:-1:-1;;;;;28070:24:0;;28101:47;:45;:47::i;30066:257::-;30176:7;30201:16;:14;:16::i;:::-;-1:-1:-1;;;;;30201:24:0;;30232:80;30296:9;30232:56;:80::i;9863:81::-;9911:7;9932;-1:-1:-1;;;;;9932:7:0;9863:81;:::o;36422:985::-;36595:8;:6;:8::i;:::-;-1:-1:-1;;;;;36595:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;36595:16:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;36595:16:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;36595:16:0;-1:-1:-1;;;;;36581:30:0;:10;:30;36573:66;;;;;-1:-1:-1;;;36573:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;36701:11;36693:44;;;;;-1:-1:-1;;;36693:44:0;;;;;;;;;;;;-1:-1:-1;;;36693:44:0;;;;;;;;;;;;;;;36847:8;:6;:8::i;:::-;-1:-1:-1;;;;;36847:21:0;;:23;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;36847:23:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;36847:23:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;36847:23:0;36833:59;;;-1:-1:-1;;;36833:59:0;;-1:-1:-1;;;;;36833:59:0;;;;;;;;;:48;;;;;;;:59;;;;;36847:23;;36833:59;;;;;;;:48;:59;;;5:2:-1;;;;30:1;27;20:12;5:2;36833:59:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;36833:59:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;36833:59:0;36820:128;;;;-1:-1:-1;;;36820:128:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37130:26;;:::i;:::-;37163:49;37195:9;37206:5;37163:31;:49::i;:::-;37130:82;;37306:52;37319:4;37325:5;37332:9;37343:6;37351;37306:12;:52::i;:::-;37368:34;;;-1:-1:-1;;;;;37368:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;36422:985;;;;:::o;24128:356::-;24209:15;24226:14;24249;24270:16;:14;:16::i;:::-;-1:-1:-1;;;;;24270:24:0;;24301:44;:42;:44::i;:::-;24270:81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;24270:81:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;24270:81:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;24270:81:0;;-1:-1:-1;24356:14:0;24373:17;24270:81;20854:33;24373:17;:10;:17;:::i;:::-;24356:34;-1:-1:-1;24395:19:0;24417:29;24428:17;24356:34;20854:33;24428:17;:10;:17;:::i;:::-;24417:6;;:29;:10;:29;:::i;:::-;24459:6;;-1:-1:-1;24395:51:0;;-1:-1:-1;;;24128:356:0;;:::o;41521:246::-;41618:7;41637:15;41658:33;:31;:33::i;:::-;41634:57;;;;41703:59;41743:7;41752:9;41703:39;:59::i;13572:109::-;12678:9;:7;:9::i;:::-;12670:54;;;;;-1:-1:-1;;;12670:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;12670:54:0;;;;;;;;;;;;;;;13645:28;13664:8;13645:18;:28::i;:::-;13572:109;:::o;37555:654::-;37712:40;37721:9;37732:10;37744:7;37712:8;:40::i;:::-;37699:92;;;;;-1:-1:-1;;;37699:92:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;37847:26;;:::i;:::-;37876:28;37894:9;37876:17;:28::i;:::-;37847:57;-1:-1:-1;37977:12:0;;37973:80;;37997:50;;;-1:-1:-1;;;37997:50:0;;38027:10;37997:50;;;;;;;;;;;;-1:-1:-1;;;;;37997:29:0;;;;;:50;;;;;-1:-1:-1;;37997:50:0;;;;;;;-1:-1:-1;37997:29:0;:50;;;5:2:-1;;;;30:1;27;20:12;5:2;37997:50:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;37997:50:0;;;;37973:80;38145:59;38158:5;38165:10;38177:9;38188:7;38197:6;38145:12;:59::i;:::-;37555:654;;;:::o;46443:226::-;46553:7;46568:14;46592:54;46629:9;46640:5;46592:36;:54::i;:::-;-1:-1:-1;46567:79:0;46443:226;-1:-1:-1;;;;46443:226:0:o;20001:177::-;12678:9;:7;:9::i;:::-;12670:54;;;;;-1:-1:-1;;;12670:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;12670:54:0;;;;;;;;;;;;;;;20058:8;;-1:-1:-1;;;;;20058:8:0;:22;20050:49;;;;;-1:-1:-1;;;20050:49:0;;;;;;;;;;;;-1:-1:-1;;;20050:49:0;;;;;;;;;;;;;;;20104:18;20125:20;;;;;:::i;:::-;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;20150:8:0;:23;;-1:-1:-1;;;;;;20150:23:0;-1:-1:-1;;;;;20150:23:0;;;;;;;;;;-1:-1:-1;20001:177:0:o;50629:139::-;50706:7;50729:34;50753:9;50729:23;:34::i;29505:262::-;29620:7;29740:9;29661:95;;;;;;;;;;;;;-1:-1:-1;;;;;29661:95:0;-1:-1:-1;;;;;29661:95:0;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;29661:95:0;;;29645:117;;;;;;29634:128;;29505:262;;;:::o;27536:186::-;27625:7;27662:54;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;27662:54:0;;;27652:65;;;;;;27641:76;;27536:186;:::o;25687:230::-;25842:64;;;;;;;;;;;;-1:-1:-1;;;;;;25842:64:0;;;;;;;;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;25842:64:0;;;;;;;25826:86;;;;;25687:230;;;;:::o;22971:171::-;23090:46;;;-1:-1:-1;;;23090:46:0;;;;;;;;;;;;;-1:-1:-1;;;;;;23090:46:0;;;;;;;26:21:-1;;;22:32;;6:49;;23090:46:0;;;;;;;23080:57;;;;;;22971:171::o;26867:226::-;27020:62;;;;;;;;;;;;-1:-1:-1;;;;;;27020:62:0;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;27020:62:0;;;;27004:84;;;;;;26867:226::o;26231:137::-;26325:37;;;-1:-1:-1;;;26325:37:0;;;;;;;;;;26:21:-1;;;26325:37:0;22:32:-1;6:49;;26325:37:0;;;;;;;26315:48;;;;;26231:137;:::o;23611:219::-;23759:60;;;-1:-1:-1;;;23759:60:0;;;;;;;;-1:-1:-1;;;;;;23759:60:0;;;;;;;;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;23759:60:0;;;;;;;23743:82;;;;;23611:219;;;;:::o;28758:170::-;28874:48;;;;;;;;;;;;;;26:21:-1;;;28874:48:0;22:32:-1;6:49;;28874:48:0;;;;;;;28864:59;;;;;28758:170;:::o;25025:162::-;25137:44;;;;;;;;;;;;;;26:21:-1;;;25137:44:0;22:32:-1;6:49;;25137:44:0;;;;;;;25127:55;;;;;25025:162;:::o;22353:170::-;22472:45;;;-1:-1:-1;;;22472:45:0;;;;;;;;;;;;;-1:-1:-1;;;;;;22472:45:0;;;;;;;26:21:-1;;;22:32;;6:49;;22472:45:0;;;;;;;22462:56;;;;;;22353:170::o;21206:121::-;21292:29;;;-1:-1:-1;;;21292:29:0;;;;;;;;;;26:21:-1;;;21292:29:0;22:32:-1;6:49;;21292:29:0;;;;;;;21282:40;;;;;21206:121;:::o;11172:98::-;11252:10;11172:98;:::o;21760:180::-;21888:46;;;-1:-1:-1;;;21888:46:0;;;;;;;;-1:-1:-1;;;;;;21888:46:0;;;;;;;;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;21888:46:0;;;;;;;21878:57;;;;;21760:180;;;;:::o;42710:1439::-;42756:20;42778:15;42885:21;42924:8;:6;:8::i;:::-;-1:-1:-1;;;;;42924:18:0;;:20;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;42924:20:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;42924:20:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;42924:20:0;42913:62;;;-1:-1:-1;;;42913:62:0;;;;-1:-1:-1;;;;;42913:60:0;;;;;;:62;;;;;42924:20;;42913:62;;;;;;;;:60;:62;;;5:2:-1;;;;30:1;27;20:12;5:2;42913:62:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;42913:62:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;42913:62:0;;-1:-1:-1;43124:18:0;;43169:41;:39;:41::i;:::-;43123:87;;;;43435:22;43478:13;43464:10;:27;:56;;43510:10;43464:56;;;43494:13;43464:56;43435:85;;43641:14;43670:1;43658:9;:13;:47;;43704:1;43658:47;;;43674:27;:12;43691:9;43674:27;:16;:27;:::i;:::-;43641:64;-1:-1:-1;43835:25:0;43863:26;:14;43641:64;43863:26;:18;:26;:::i;:::-;43835:54;;43894:19;43920:58;43960:17;43920:35;:33;:35::i;:58::-;43894:84;-1:-1:-1;44130:13:0;;-1:-1:-1;;;;;;;42710:1439:0;;:::o;24696:163::-;24769:16;:14;:16::i;:::-;-1:-1:-1;;;;;24769:24:0;;24799:38;:36;:38::i;:::-;24843:6;24769:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;23869:254:0;23975:14;23992:30;24015:6;23992:18;:7;20854:33;23992:18;:11;:18;:::i;:30::-;23975:47;;24027:16;:14;:16::i;:::-;-1:-1:-1;;;;;24027:24:0;;24057:44;:42;:44::i;:::-;24107:6;24027:91;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;24027:91:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;24027:91:0;;;;23869:254;;;:::o;6315:98::-;6368:7;6389:19;:2;5749:19;6389;:6;:19;:::i;1369:136::-;1427:7;1454:43;1458:1;1461;1454:43;;;;;;;;;;;;;;;;;:3;:43::i;3224:132::-;3282:7;3309:39;3313:1;3316;3309:39;;;;;;;;;;;;;;;;;:3;:39::i;913:181::-;971:7;1003:5;;;1027:6;;;;1019:46;;;;;-1:-1:-1;;;1019:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;28164:180;28252:7;28285:53;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;28285:53:0;;;28275:64;;;;;;28268:71;;28164:180;:::o;30328:260::-;30442:7;30561:9;30483:94;;;;;;;;;;;;;-1:-1:-1;;;;;30483:94:0;-1:-1:-1;;;;;30483:94:0;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;30483:94:0;;;30467:116;;;;;;30456:127;;30328:260;;;:::o;51400:659::-;51498:27;;:::i;:::-;51586:26;51614;;:::i;:::-;51648:54;51685:9;51696:5;51648:36;:54::i;:::-;51585:117;;;;51786:90;51827:9;51842:5;51853:18;51786:35;:90::i;:::-;51976:58;52017:9;52028:5;51976:40;:58::i;:::-;52048:6;51400:659;-1:-1:-1;;;;51400:659:0:o;47717:1136::-;47869:49;47889:9;47900:8;47910:7;47869:19;:49::i;:::-;47965:9;47961:774;;;48063:19;48075:6;48063:11;:19::i;:::-;48165:35;48182:9;48193:6;48165:16;:35::i;:::-;48290:37;48299:9;48310:8;48320:6;48290:8;:37::i;:::-;47961:774;;;48472:19;48484:6;48472:11;:19::i;:::-;48574:35;48591:9;48602:6;48574:16;:35::i;:::-;48692:37;48701:9;48712:8;48722:6;48692:8;:37::i;:::-;48840:8;:6;:8::i;24489:174::-;24607:50;;;;;;;;;;;;;;26:21:-1;;;24607:50:0;22:32:-1;6:49;;24607:50:0;;;;;;;24597:61;;;;;24489:174;:::o;2285:471::-;2343:7;2588:6;2584:47;;-1:-1:-1;2618:1:0;2611:8;;2584:47;2655:5;;;2659:1;2655;:5;:1;2679:5;;;;;:10;2671:56;;;;-1:-1:-1;;;2671:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40670:767;40787:7;40802:22;40826:18;40859:78;40921:9;40859:54;:78::i;:::-;40944:64;40998:9;40944:53;:64::i;:::-;40801:213;;;;41121:31;41159:63;41187:34;41211:9;41187:23;:34::i;:::-;41159:23;:7;41171:10;41159:23;:11;:23;:::i;:::-;:27;:63;:27;:63;:::i;:::-;41121:101;-1:-1:-1;41389:43:0;:14;41121:101;41389:43;:18;:43;:::i;:::-;41382:50;40670:767;-1:-1:-1;;;;;;40670:767:0:o;13787:229::-;-1:-1:-1;;;;;13861:22:0;;13853:73;;;;-1:-1:-1;;;13853:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13963:6;;13942:38;;-1:-1:-1;;;;;13942:38:0;;;;13963:6;;13942:38;;13963:6;;13942:38;13991:6;:17;;-1:-1:-1;;;;;;13991:17:0;-1:-1:-1;;;;;13991:17:0;;;;;;;;;;13787:229::o;50362:201::-;50468:4;50479:13;50495:35;50511:9;50522:7;50495:15;:35::i;:::-;-1:-1:-1;;;50542:16:0;;50362:201;-1:-1:-1;;;;50362:201:0:o;46732:907::-;46801:27;;:::i;:::-;46888:13;46903:26;;:::i;:::-;46937:59;46974:9;46985:10;46937:36;:59::i;:::-;46887:109;;;;47064:61;47100:9;47111:10;47123:1;47064:35;:61::i;:::-;47204:90;47243:9;47258:10;47274:6;:15;;;47204:33;:90::i;:::-;47299:63;47340:9;47351:10;47299:40;:63::i;:::-;47431:9;;47420:45;;;-1:-1:-1;;;47420:45:0;;47447:10;47420:45;;;;;;;;;;;;-1:-1:-1;;;;;47431:9:0;;;;47420:26;;:45;;;;;;;;;;;;;;;47431:9;;47420:45;;;5:2:-1;;;;30:1;27;20:12;5:2;47420:45:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;47420:45:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;47420:45:0;47407:86;;;;;-1:-1:-1;;;47407:86:0;;;;;;;;;;;;-1:-1:-1;;;47407:86:0;;;;;;;;;;;;;;;47606:8;:6;:8::i;45329:986::-;45441:15;45458:27;;:::i;:::-;45599:8;:6;:8::i;:::-;-1:-1:-1;;;;;45599:21:0;;:23;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;45599:23:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;45599:23:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;45599:23:0;45585:59;;;-1:-1:-1;;;45585:59:0;;-1:-1:-1;;;;;45585:59:0;;;;;;;;;:48;;;;;;;:59;;;;;45599:23;;45585:59;;;;;;;:48;:59;;;5:2:-1;;;;30:1;27;20:12;5:2;45585:59:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;45585:59:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;45585:59:0;45576:128;;-1:-1:-1;;45676:21:0;;;;;;;;45673:1;45676:21;;;;;;;;;;;;;;;45665:33;;45576:128;45782:15;45800:53;45836:9;45847:5;45800:35;:53::i;:::-;45782:71;;45919:14;45936:52;45971:9;45982:5;45936:34;:52::i;:::-;45919:69;;46058:14;46076:26;;:::i;:::-;46110:42;46135:9;46146:5;46110:24;:42::i;:::-;46057:95;;;;;46210:26;46239:31;46263:6;46239:19;46250:7;46239:6;:10;;:19;;;;:::i;:31::-;46210:60;-1:-1:-1;46303:6:0;;-1:-1:-1;;;;;45329:986:0;;;;;;:::o;1842:192::-;1928:7;1964:12;1956:6;;;;1948:29;;;;-1:-1:-1;;;1948:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;1948:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;2000:5:0;;;1842:192::o;3886:345::-;3972:7;4074:12;4067:5;4059:28;;;;-1:-1:-1;;;4059:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27:10:-1;;8:100;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;4059:28:0;;4098:9;4114:1;4110;:5;;;;;;;3886:345;-1:-1:-1;;;;;3886:345:0:o;25214:230::-;25336:16;:14;:16::i;:::-;-1:-1:-1;;;;;25336:24:0;;25366:56;25405:9;25416:5;25366:38;:56::i;52844:314::-;52951:21;52975:34;52999:9;52975:23;:34::i;:::-;52951:58;;53067:13;53018:45;53046:9;53057:5;53018:27;:45::i;:::-;:62;53014:140;;53088:60;53116:9;53127:5;53134:13;53088:27;:60::i;38267:802::-;38468:22;38497:67;38537:7;:15;;;38554:9;38497:39;:67::i;:::-;38468:96;;38609:69;38643:9;38654:5;38661:7;:16;;;38609:33;:69::i;:::-;38727:14;;38683:59;;:43;:59::i;:::-;38747;38790:7;:15;;;38747:42;:59::i;:::-;38811:55;38849:7;:16;;;38811:37;:55::i;:::-;38871:94;38931:9;38946:14;38871:54;:94::i;:::-;38970;39029:9;39044:7;:15;;;38970:53;:94::i;:::-;38267:802;;;;:::o;49086:151::-;49136:13;49152:20;:18;:20::i;:::-;49136:36;-1:-1:-1;49185:17:0;49136:36;49195:6;49185:17;:9;:17;:::i;:::-;49177:25;;49207;49226:5;49207:18;:25::i;50831:205::-;50905:13;50921:34;50945:9;50921:23;:34::i;:::-;50905:50;-1:-1:-1;50968:17:0;50905:50;50978:6;50968:17;:9;:17;:::i;:::-;50960:25;;50990:41;51014:9;51025:5;50990:23;:41::i;49754:229::-;49850:13;49866:35;49882:9;49893:7;49866:15;:35::i;:::-;49850:51;-1:-1:-1;49914:17:0;49850:51;49924:6;49914:17;:9;:17;:::i;:::-;49906:25;;49936:42;49952:9;49963:7;49972:5;49936:15;:42::i;49311:151::-;49361:13;49377:20;:18;:20::i;:::-;49361:36;-1:-1:-1;49410:17:0;49361:36;49420:6;49410:17;:9;:17;:::i;51104:221::-;51178:13;51194:34;51218:9;51194:23;:34::i;:::-;51178:50;-1:-1:-1;51233:17:0;51253;51178:50;51263:6;51253:17;:9;:17;:::i;:::-;51233:37;;51275:45;51299:9;51310;51275:23;:45::i;50058:229::-;50154:13;50170:35;50186:9;50197:7;50170:15;:35::i;:::-;50154:51;-1:-1:-1;50218:17:0;50154:51;50228:6;50218:17;:9;:17;:::i;26401:226::-;26521:16;:14;:16::i;:::-;-1:-1:-1;;;;;26521:24:0;;26551:54;26588:9;26599:5;26551:36;:54::i;52333:423::-;52443:7;52457:13;52473:45;52501:9;52512:5;52473:27;:45::i;:::-;52457:61;;52523:13;52539:34;52563:9;52539:23;:34::i;:::-;52523:50;-1:-1:-1;52578:16:0;52597;52523:50;52607:5;52597:16;:9;:16;:::i;:::-;52578:35;;52618:21;52642:33;52658:9;52669:5;52642:15;:33::i;:::-;52618:57;-1:-1:-1;52680:13:0;52696:27;:8;52618:57;52696:27;:12;:27;:::i;:::-;52680:43;;52735:16;:5;:14;:16::i;:::-;52728:23;52333:423;-1:-1:-1;;;;;;;;52333:423:0:o;44210:996::-;44314:15;44335:22;44363:27;;:::i;:::-;44476:26;44505:33;44521:9;44532:5;44505:15;:33::i;:::-;44476:62;;44648:20;44675:51;44709:9;44720:5;44675:33;:51::i;:::-;44648:78;;44808:14;44824:15;44841:16;44865:33;:31;:33::i;:::-;44807:91;;;;;;45007:14;45040:12;45028:8;:24;;:102;;45129:1;45028:102;;;45060:61;:50;45091:18;45060:26;:8;45073:12;45060:26;:12;:26;:::i;:50::-;:59;:61::i;:::-;45161:39;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45007:123:0;;-1:-1:-1;45151:8:0;-1:-1:-1;45161:39:0;-1:-1:-1;;;44210:996:0;;;;;:::o;23169:214::-;23283:16;:14;:16::i;:::-;-1:-1:-1;;;;;23283:24:0;;23313:48;23344:9;23355:5;23313:30;:48::i;27136:188::-;27224:16;:14;:16::i;:::-;-1:-1:-1;;;;;27224:24:0;;27254:48;:46;:48::i;27764:190::-;27853:16;:14;:16::i;:::-;-1:-1:-1;;;;;27853:24:0;;27883:47;:45;:47::i;28381:177::-;28461:16;:14;:16::i;:::-;-1:-1:-1;;;;;28461:24:0;;28491:42;:40;:42::i;28982:254::-;29105:16;:14;:16::i;:::-;-1:-1:-1;;;;;29105:24:0;;29135:79;29199:9;29135:57;:79::i;:::-;29220:6;29105:126;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;29105:126:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;29105:126:0;;;;28982:254;;:::o;29820:241::-;29942:16;:14;:16::i;:::-;-1:-1:-1;;;;;29942:24:0;;29972:67;30029:9;29972:56;:67::i;20906:142::-;20964:11;20978:23;:21;:23::i;:::-;20964:37;;21006:16;:14;:16::i;:::-;-1:-1:-1;;;;;21006:24:0;;21031:3;21036:6;21006:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;21963:185:0;22050:11;22064:37;22091:9;22064:26;:37::i;:::-;22050:51;;22106:16;:14;:16::i;:::-;-1:-1:-1;;;;;22106:24:0;;22131:3;22136:6;22106:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;21342:203:0;21446:11;21460:38;21479:9;21490:7;21460:18;:38::i;:::-;21446:52;;21503:16;:14;:16::i;:::-;-1:-1:-1;;;;;21503:24:0;;21528:3;21533:6;21503:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;21503:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;21503:37:0;;;;21342:203;;;;:::o;6648:98::-;6701:7;6722:19;:2;5749:19;6722;:6;:19;:::i;35823:17338::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;:::o

Swarm Source

bzzr://d47666347b6303bc0919f6de2d0a3784ecb78f938d3c7b790935a7f2e560fd1a
Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading

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.