ETH Price: $2,227.87 (+3.53%)
Gas: 0.66 Gwei
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Withdraw108224022020-09-08 17:32:141635 days ago1599586334IN
0x44A19177...EBd6330f2
0 ETH0.04752458117
Withdraw108223152020-09-08 17:14:571635 days ago1599585297IN
0x44A19177...EBd6330f2
0 ETH0.05075541117
Withdraw108222152020-09-08 16:54:191635 days ago1599584059IN
0x44A19177...EBd6330f2
0 ETH0.05112323119
Withdraw108222152020-09-08 16:54:191635 days ago1599584059IN
0x44A19177...EBd6330f2
0 ETH0.05162303119
Withdraw108222142020-09-08 16:54:161635 days ago1599584056IN
0x44A19177...EBd6330f2
0 ETH0.05112323119
Withdraw108222142020-09-08 16:54:161635 days ago1599584056IN
0x44A19177...EBd6330f2
0 ETH0.05112323119
Withdraw108222142020-09-08 16:54:161635 days ago1599584056IN
0x44A19177...EBd6330f2
0 ETH0.05112323119
Withdraw108222142020-09-08 16:54:161635 days ago1599584056IN
0x44A19177...EBd6330f2
0 ETH0.05112323119
Withdraw108222142020-09-08 16:54:161635 days ago1599584056IN
0x44A19177...EBd6330f2
0 ETH0.05112323119
Withdraw108222142020-09-08 16:54:161635 days ago1599584056IN
0x44A19177...EBd6330f2
0 ETH0.05112323119
Withdraw108222142020-09-08 16:54:161635 days ago1599584056IN
0x44A19177...EBd6330f2
0 ETH0.05112323119
Withdraw108222142020-09-08 16:54:161635 days ago1599584056IN
0x44A19177...EBd6330f2
0 ETH0.05162303119
Withdraw108222122020-09-08 16:53:591635 days ago1599584039IN
0x44A19177...EBd6330f2
0 ETH0.05112323119
Withdraw108222122020-09-08 16:53:591635 days ago1599584039IN
0x44A19177...EBd6330f2
0 ETH0.0500483119
Withdraw108222122020-09-08 16:53:591635 days ago1599584039IN
0x44A19177...EBd6330f2
0 ETH0.05004973119
Withdraw108222122020-09-08 16:53:591635 days ago1599584039IN
0x44A19177...EBd6330f2
0 ETH0.05112323119
Withdraw108222122020-09-08 16:53:591635 days ago1599584039IN
0x44A19177...EBd6330f2
0 ETH0.05112323119
Withdraw108222122020-09-08 16:53:591635 days ago1599584039IN
0x44A19177...EBd6330f2
0 ETH0.05112323119
Withdraw108222122020-09-08 16:53:591635 days ago1599584039IN
0x44A19177...EBd6330f2
0 ETH0.05004973119
Withdraw108222122020-09-08 16:53:591635 days ago1599584039IN
0x44A19177...EBd6330f2
0 ETH0.05112323119
Withdraw108222122020-09-08 16:53:591635 days ago1599584039IN
0x44A19177...EBd6330f2
0 ETH0.05112323119
Withdraw108222122020-09-08 16:53:591635 days ago1599584039IN
0x44A19177...EBd6330f2
0 ETH0.05112323119
Withdraw108222122020-09-08 16:53:591635 days ago1599584039IN
0x44A19177...EBd6330f2
0 ETH0.05112323119
Withdraw108222122020-09-08 16:53:591635 days ago1599584039IN
0x44A19177...EBd6330f2
0 ETH0.05162303119
Withdraw108222112020-09-08 16:53:561635 days ago1599584036IN
0x44A19177...EBd6330f2
0 ETH0.05112323119
View all transactions

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block
From
To
106950912020-08-20 5:09:231655 days ago1597900163
0x44A19177...EBd6330f2
 Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Withdraw

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 2020-08-20
*/

// 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/token/ERC20/IERC20.sol

pragma solidity ^0.5.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP. Does not include
 * the optional functions; to access them see {ERC20Detailed}.
 */
interface IERC20 {
	/**
	 * @dev Returns the amount of tokens in existence.
	 */
	function totalSupply() external view returns (uint256);

	/**
	 * @dev Returns the amount of tokens owned by `account`.
	 */
	function balanceOf(address account) external view returns (uint256);

	/**
	 * @dev Moves `amount` tokens from the caller's account to `recipient`.
	 *
	 * Returns a boolean value indicating whether the operation succeeded.
	 *
	 * Emits a {Transfer} event.
	 */
	function transfer(address recipient, uint256 amount)
		external
		returns (bool);

	/**
	 * @dev Returns the remaining number of tokens that `spender` will be
	 * allowed to spend on behalf of `owner` through {transferFrom}. This is
	 * zero by default.
	 *
	 * This value changes when {approve} or {transferFrom} are called.
	 */
	function allowance(address owner, address spender)
		external
		view
		returns (uint256);

	/**
	 * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
	 *
	 * Returns a boolean value indicating whether the operation succeeded.
	 *
	 * IMPORTANT: Beware that changing an allowance with this method brings the risk
	 * that someone may use both the old and the new allowance by unfortunate
	 * transaction ordering. One possible solution to mitigate this race
	 * condition is to first reduce the spender's allowance to 0 and set the
	 * desired value afterwards:
	 * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
	 *
	 * Emits an {Approval} event.
	 */
	function approve(address spender, uint256 amount) external returns (bool);

	/**
	 * @dev Moves `amount` tokens from `sender` to `recipient` using the
	 * allowance mechanism. `amount` is then deducted from the caller's
	 * allowance.
	 *
	 * Returns a boolean value indicating whether the operation succeeded.
	 *
	 * Emits a {Transfer} event.
	 */
	function transferFrom(
		address sender,
		address recipient,
		uint256 amount
	) external returns (bool);

	/**
	 * @dev Emitted when `value` tokens are moved from one account (`from`) to
	 * another (`to`).
	 *
	 * Note that `value` may be zero.
	 */
	event Transfer(address indexed from, address indexed to, uint256 value);

	/**
	 * @dev Emitted when the allowance of a `spender` for an `owner` is set by
	 * a call to {approve}. `value` is the new allowance.
	 */
	event Approval(
		address indexed owner,
		address indexed spender,
		uint256 value
	);
}

// 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: @openzeppelin/contracts/token/ERC20/ERC20.sol

pragma solidity ^0.5.0;

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20Mintable}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin guidelines: functions revert instead
 * of returning `false` on failure. This behavior is nonetheless conventional
 * and does not conflict with the expectations of ERC20 applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20 {
	using SafeMath for uint256;

	mapping(address => uint256) private _balances;

	mapping(address => mapping(address => uint256)) private _allowances;

	uint256 private _totalSupply;

	/**
	 * @dev See {IERC20-totalSupply}.
	 */
	function totalSupply() public view returns (uint256) {
		return _totalSupply;
	}

	/**
	 * @dev See {IERC20-balanceOf}.
	 */
	function balanceOf(address account) public view returns (uint256) {
		return _balances[account];
	}

	/**
	 * @dev See {IERC20-transfer}.
	 *
	 * Requirements:
	 *
	 * - `recipient` cannot be the zero address.
	 * - the caller must have a balance of at least `amount`.
	 */
	function transfer(address recipient, uint256 amount) public returns (bool) {
		_transfer(_msgSender(), recipient, amount);
		return true;
	}

	/**
	 * @dev See {IERC20-allowance}.
	 */
	function allowance(address owner, address spender)
		public
		view
		returns (uint256)
	{
		return _allowances[owner][spender];
	}

	/**
	 * @dev See {IERC20-approve}.
	 *
	 * Requirements:
	 *
	 * - `spender` cannot be the zero address.
	 */
	function approve(address spender, uint256 amount) public returns (bool) {
		_approve(_msgSender(), spender, amount);
		return true;
	}

	/**
	 * @dev See {IERC20-transferFrom}.
	 *
	 * Emits an {Approval} event indicating the updated allowance. This is not
	 * required by the EIP. See the note at the beginning of {ERC20};
	 *
	 * Requirements:
	 * - `sender` and `recipient` cannot be the zero address.
	 * - `sender` must have a balance of at least `amount`.
	 * - the caller must have allowance for `sender`'s tokens of at least
	 * `amount`.
	 */
	function transferFrom(
		address sender,
		address recipient,
		uint256 amount
	) public returns (bool) {
		_transfer(sender, recipient, amount);
		_approve(
			sender,
			_msgSender(),
			_allowances[sender][_msgSender()].sub(
				amount,
				"ERC20: transfer amount exceeds allowance"
			)
		);
		return true;
	}

	/**
	 * @dev Atomically increases the allowance granted to `spender` by the caller.
	 *
	 * This is an alternative to {approve} that can be used as a mitigation for
	 * problems described in {IERC20-approve}.
	 *
	 * Emits an {Approval} event indicating the updated allowance.
	 *
	 * Requirements:
	 *
	 * - `spender` cannot be the zero address.
	 */
	function increaseAllowance(address spender, uint256 addedValue)
		public
		returns (bool)
	{
		_approve(
			_msgSender(),
			spender,
			_allowances[_msgSender()][spender].add(addedValue)
		);
		return true;
	}

	/**
	 * @dev Atomically decreases the allowance granted to `spender` by the caller.
	 *
	 * This is an alternative to {approve} that can be used as a mitigation for
	 * problems described in {IERC20-approve}.
	 *
	 * Emits an {Approval} event indicating the updated allowance.
	 *
	 * Requirements:
	 *
	 * - `spender` cannot be the zero address.
	 * - `spender` must have allowance for the caller of at least
	 * `subtractedValue`.
	 */
	function decreaseAllowance(address spender, uint256 subtractedValue)
		public
		returns (bool)
	{
		_approve(
			_msgSender(),
			spender,
			_allowances[_msgSender()][spender].sub(
				subtractedValue,
				"ERC20: decreased allowance below zero"
			)
		);
		return true;
	}

	/**
	 * @dev Moves tokens `amount` from `sender` to `recipient`.
	 *
	 * This is internal function is equivalent to {transfer}, and can be used to
	 * e.g. implement automatic token fees, slashing mechanisms, etc.
	 *
	 * Emits a {Transfer} event.
	 *
	 * Requirements:
	 *
	 * - `sender` cannot be the zero address.
	 * - `recipient` cannot be the zero address.
	 * - `sender` must have a balance of at least `amount`.
	 */
	function _transfer(
		address sender,
		address recipient,
		uint256 amount
	) internal {
		require(sender != address(0), "ERC20: transfer from the zero address");
		require(recipient != address(0), "ERC20: transfer to the zero address");

		_balances[sender] = _balances[sender].sub(
			amount,
			"ERC20: transfer amount exceeds balance"
		);
		_balances[recipient] = _balances[recipient].add(amount);
		emit Transfer(sender, recipient, amount);
	}

	/** @dev Creates `amount` tokens and assigns them to `account`, increasing
	 * the total supply.
	 *
	 * Emits a {Transfer} event with `from` set to the zero address.
	 *
	 * Requirements
	 *
	 * - `to` cannot be the zero address.
	 */
	function _mint(address account, uint256 amount) internal {
		require(account != address(0), "ERC20: mint to the zero address");

		_totalSupply = _totalSupply.add(amount);
		_balances[account] = _balances[account].add(amount);
		emit Transfer(address(0), account, amount);
	}

	/**
	 * @dev Destroys `amount` tokens from `account`, reducing the
	 * total supply.
	 *
	 * Emits a {Transfer} event with `to` set to the zero address.
	 *
	 * Requirements
	 *
	 * - `account` cannot be the zero address.
	 * - `account` must have at least `amount` tokens.
	 */
	function _burn(address account, uint256 amount) internal {
		require(account != address(0), "ERC20: burn from the zero address");

		_balances[account] = _balances[account].sub(
			amount,
			"ERC20: burn amount exceeds balance"
		);
		_totalSupply = _totalSupply.sub(amount);
		emit Transfer(account, address(0), amount);
	}

	/**
	 * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.
	 *
	 * This is internal function is equivalent to `approve`, and can be used to
	 * e.g. set automatic allowances for certain subsystems, etc.
	 *
	 * Emits an {Approval} event.
	 *
	 * Requirements:
	 *
	 * - `owner` cannot be the zero address.
	 * - `spender` cannot be the zero address.
	 */
	function _approve(
		address owner,
		address spender,
		uint256 amount
	) internal {
		require(owner != address(0), "ERC20: approve from the zero address");
		require(spender != address(0), "ERC20: approve to the zero address");

		_allowances[owner][spender] = amount;
		emit Approval(owner, spender, amount);
	}

	/**
	 * @dev Destroys `amount` tokens from `account`.`amount` is then deducted
	 * from the caller's allowance.
	 *
	 * See {_burn} and {_approve}.
	 */
	function _burnFrom(address account, uint256 amount) internal {
		_burn(account, amount);
		_approve(
			account,
			_msgSender(),
			_allowances[account][_msgSender()].sub(
				amount,
				"ERC20: burn amount exceeds allowance"
			)
		);
	}
}

// File: @openzeppelin/contracts/access/Roles.sol

pragma solidity ^0.5.0;

/**
 * @title Roles
 * @dev Library for managing addresses assigned to a Role.
 */
library Roles {
	struct Role {
		mapping(address => bool) bearer;
	}

	/**
	 * @dev Give an account access to this role.
	 */
	function add(Role storage role, address account) internal {
		require(!has(role, account), "Roles: account already has role");
		role.bearer[account] = true;
	}

	/**
	 * @dev Remove an account's access to this role.
	 */
	function remove(Role storage role, address account) internal {
		require(has(role, account), "Roles: account does not have role");
		role.bearer[account] = false;
	}

	/**
	 * @dev Check if an account has this role.
	 * @return bool
	 */
	function has(Role storage role, address account)
		internal
		view
		returns (bool)
	{
		require(account != address(0), "Roles: account is the zero address");
		return role.bearer[account];
	}
}

// File: @openzeppelin/contracts/access/roles/MinterRole.sol

pragma solidity ^0.5.0;

contract MinterRole is Context {
	using Roles for Roles.Role;

	event MinterAdded(address indexed account);
	event MinterRemoved(address indexed account);

	Roles.Role private _minters;

	constructor() internal {
		_addMinter(_msgSender());
	}

	modifier onlyMinter() {
		require(
			isMinter(_msgSender()),
			"MinterRole: caller does not have the Minter role"
		);
		_;
	}

	function isMinter(address account) public view returns (bool) {
		return _minters.has(account);
	}

	function addMinter(address account) public onlyMinter {
		_addMinter(account);
	}

	function renounceMinter() public {
		_removeMinter(_msgSender());
	}

	function _addMinter(address account) internal {
		_minters.add(account);
		emit MinterAdded(account);
	}

	function _removeMinter(address account) internal {
		_minters.remove(account);
		emit MinterRemoved(account);
	}
}

// File: @openzeppelin/contracts/token/ERC20/ERC20Mintable.sol

pragma solidity ^0.5.0;

/**
 * @dev Extension of {ERC20} that adds a set of accounts with the {MinterRole},
 * which have permission to mint (create) new tokens as they see fit.
 *
 * At construction, the deployer of the contract is the only minter.
 */
contract ERC20Mintable is ERC20, MinterRole {
	/**
	 * @dev See {ERC20-_mint}.
	 *
	 * Requirements:
	 *
	 * - the caller must have the {MinterRole}.
	 */
	function mint(address account, uint256 amount)
		public
		onlyMinter
		returns (bool)
	{
		_mint(account, amount);
		return true;
	}
}

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

pragma solidity ^0.5.0;

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

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

	/**
	 * Returns multiplied the number by 10^18.
	 * This is used when there is a very large difference between the two numbers passed to the `outOf` function.
	 */
	function mulBasis(uint256 _a) internal pure returns (uint256) {
		return _a.mul(basisValue);
	}

	/**
	 * Returns by changing the numerical value being emulated to the original number of digits.
	 */
	function divBasis(uint256 _a) internal pure returns (uint256) {
		return _a.div(basisValue);
	}
}

// File: contracts/src/common/lifecycle/Killable.sol

pragma solidity ^0.5.0;

/**
 * A module that allows contracts to self-destruct.
 */
contract Killable {
	address payable public _owner;

	/**
	 * Initialized with the deployer as the owner.
	 */
	constructor() internal {
		_owner = msg.sender;
	}

	/**
	 * Self-destruct the contract.
	 * This function can only be executed by the owner.
	 */
	function kill() public {
		require(msg.sender == _owner, "only owner method");
		selfdestruct(_owner);
	}
}

// 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/interface/IGroup.sol

pragma solidity ^0.5.0;

contract IGroup {
	function isGroup(address _addr) public view returns (bool);

	function addGroup(address _addr) external;

	function getGroupKey(address _addr) internal pure returns (bytes32) {
		return keccak256(abi.encodePacked("_group", _addr));
	}
}

// File: contracts/src/common/validate/AddressValidator.sol

pragma solidity ^0.5.0;

/**
 * A module that provides common validations patterns.
 */
contract AddressValidator {
	string constant errorMessage = "this is illegal address";

	/**
	 * Validates passed address is not a zero address.
	 */
	function validateIllegalAddress(address _addr) external pure {
		require(_addr != address(0), errorMessage);
	}

	/**
	 * Validates passed address is included in an address set.
	 */
	function validateGroup(address _addr, address _groupAddr) external view {
		require(IGroup(_groupAddr).isGroup(_addr), errorMessage);
	}

	/**
	 * Validates passed address is included in two address sets.
	 */
	function validateGroups(
		address _addr,
		address _groupAddr1,
		address _groupAddr2
	) external view {
		if (IGroup(_groupAddr1).isGroup(_addr)) {
			return;
		}
		require(IGroup(_groupAddr2).isGroup(_addr), errorMessage);
	}

	/**
	 * Validates that the address of the first argument is equal to the address of the second argument.
	 */
	function validateAddress(address _addr, address _target) external pure {
		require(_addr == _target, errorMessage);
	}

	/**
	 * Validates passed address equals to the two addresses.
	 */
	function validateAddresses(
		address _addr,
		address _target1,
		address _target2
	) external pure {
		if (_addr == _target1) {
			return;
		}
		require(_addr == _target2, errorMessage);
	}

	/**
	 * Validates passed address equals to the three addresses.
	 */
	function validate3Addresses(
		address _addr,
		address _target1,
		address _target2,
		address _target3
	) external pure {
		if (_addr == _target1) {
			return;
		}
		if (_addr == _target2) {
			return;
		}
		require(_addr == _target3, errorMessage);
	}
}

// File: contracts/src/common/validate/UsingValidator.sol

pragma solidity ^0.5.0;

// prettier-ignore

/**
 * Module for contrast handling AddressValidator.
 */
contract UsingValidator {
	AddressValidator private _validator;

	/**
	 * Create a new AddressValidator contract when initialize.
	 */
	constructor() public {
		_validator = new AddressValidator();
	}

	/**
	 * Returns the set AddressValidator address.
	 */
	function addressValidator() internal view returns (AddressValidator) {
		return _validator;
	}
}

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

pragma solidity ^0.5.0;

/**
 * A registry contract to hold the latest contract addresses.
 * Dev Protocol will be upgradeable by this contract.
 */
contract AddressConfig is Ownable, UsingValidator, Killable {
	address public token = 0x98626E2C9231f03504273d55f397409deFD4a093;
	address public allocator;
	address public allocatorStorage;
	address public withdraw;
	address public withdrawStorage;
	address public marketFactory;
	address public marketGroup;
	address public propertyFactory;
	address public propertyGroup;
	address public metricsGroup;
	address public metricsFactory;
	address public policy;
	address public policyFactory;
	address public policySet;
	address public policyGroup;
	address public lockup;
	address public lockupStorage;
	address public voteTimes;
	address public voteTimesStorage;
	address public voteCounter;
	address public voteCounterStorage;

	/**
	 * Set the latest Allocator contract address.
	 * Only the owner can execute this function.
	 */
	function setAllocator(address _addr) external onlyOwner {
		allocator = _addr;
	}

	/**
	 * Set the latest AllocatorStorage contract address.
	 * Only the owner can execute this function.
	 * NOTE: But currently, the AllocatorStorage contract is not used.
	 */
	function setAllocatorStorage(address _addr) external onlyOwner {
		allocatorStorage = _addr;
	}

	/**
	 * Set the latest Withdraw contract address.
	 * Only the owner can execute this function.
	 */
	function setWithdraw(address _addr) external onlyOwner {
		withdraw = _addr;
	}

	/**
	 * Set the latest WithdrawStorage contract address.
	 * Only the owner can execute this function.
	 */
	function setWithdrawStorage(address _addr) external onlyOwner {
		withdrawStorage = _addr;
	}

	/**
	 * Set the latest MarketFactory contract address.
	 * Only the owner can execute this function.
	 */
	function setMarketFactory(address _addr) external onlyOwner {
		marketFactory = _addr;
	}

	/**
	 * Set the latest MarketGroup contract address.
	 * Only the owner can execute this function.
	 */
	function setMarketGroup(address _addr) external onlyOwner {
		marketGroup = _addr;
	}

	/**
	 * Set the latest PropertyFactory contract address.
	 * Only the owner can execute this function.
	 */
	function setPropertyFactory(address _addr) external onlyOwner {
		propertyFactory = _addr;
	}

	/**
	 * Set the latest PropertyGroup contract address.
	 * Only the owner can execute this function.
	 */
	function setPropertyGroup(address _addr) external onlyOwner {
		propertyGroup = _addr;
	}

	/**
	 * Set the latest MetricsFactory contract address.
	 * Only the owner can execute this function.
	 */
	function setMetricsFactory(address _addr) external onlyOwner {
		metricsFactory = _addr;
	}

	/**
	 * Set the latest MetricsGroup contract address.
	 * Only the owner can execute this function.
	 */
	function setMetricsGroup(address _addr) external onlyOwner {
		metricsGroup = _addr;
	}

	/**
	 * Set the latest PolicyFactory contract address.
	 * Only the owner can execute this function.
	 */
	function setPolicyFactory(address _addr) external onlyOwner {
		policyFactory = _addr;
	}

	/**
	 * Set the latest PolicyGroup contract address.
	 * Only the owner can execute this function.
	 */
	function setPolicyGroup(address _addr) external onlyOwner {
		policyGroup = _addr;
	}

	/**
	 * Set the latest PolicySet contract address.
	 * Only the owner can execute this function.
	 */
	function setPolicySet(address _addr) external onlyOwner {
		policySet = _addr;
	}

	/**
	 * Set the latest Policy contract address.
	 * Only the latest PolicyFactory contract can execute this function.
	 */
	function setPolicy(address _addr) external {
		addressValidator().validateAddress(msg.sender, policyFactory);
		policy = _addr;
	}

	/**
	 * Set the latest Dev contract address.
	 * Only the owner can execute this function.
	 */
	function setToken(address _addr) external onlyOwner {
		token = _addr;
	}

	/**
	 * Set the latest Lockup contract address.
	 * Only the owner can execute this function.
	 */
	function setLockup(address _addr) external onlyOwner {
		lockup = _addr;
	}

	/**
	 * Set the latest LockupStorage contract address.
	 * Only the owner can execute this function.
	 * NOTE: But currently, the LockupStorage contract is not used as a stand-alone because it is inherited from the Lockup contract.
	 */
	function setLockupStorage(address _addr) external onlyOwner {
		lockupStorage = _addr;
	}

	/**
	 * Set the latest VoteTimes contract address.
	 * Only the owner can execute this function.
	 * NOTE: But currently, the VoteTimes contract is not used.
	 */
	function setVoteTimes(address _addr) external onlyOwner {
		voteTimes = _addr;
	}

	/**
	 * Set the latest VoteTimesStorage contract address.
	 * Only the owner can execute this function.
	 * NOTE: But currently, the VoteTimesStorage contract is not used.
	 */
	function setVoteTimesStorage(address _addr) external onlyOwner {
		voteTimesStorage = _addr;
	}

	/**
	 * Set the latest VoteCounter contract address.
	 * Only the owner can execute this function.
	 */
	function setVoteCounter(address _addr) external onlyOwner {
		voteCounter = _addr;
	}

	/**
	 * Set the latest VoteCounterStorage contract address.
	 * Only the owner can execute this function.
	 * NOTE: But currently, the VoteCounterStorage contract is not used as a stand-alone because it is inherited from the VoteCounter contract.
	 */
	function setVoteCounterStorage(address _addr) external onlyOwner {
		voteCounterStorage = _addr;
	}
}

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

pragma solidity ^0.5.0;

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

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

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

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

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

pragma solidity ^0.5.0;

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

/**
 * Module for contrast handling EternalStorage.
 */
contract UsingStorage is Ownable {
	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/withdraw/WithdrawStorage.sol

pragma solidity ^0.5.0;

contract WithdrawStorage is UsingStorage, UsingConfig, UsingValidator {
	// solium-disable-next-line no-empty-blocks
	constructor(address _config) public UsingConfig(_config) {}

	// RewardsAmount
	function setRewardsAmount(address _property, uint256 _value) external {
		addressValidator().validateAddress(msg.sender, config().withdraw());

		eternalStorage().setUint(getRewardsAmountKey(_property), _value);
	}

	function getRewardsAmount(address _property)
		external
		view
		returns (uint256)
	{
		return eternalStorage().getUint(getRewardsAmountKey(_property));
	}

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

	// CumulativePrice
	function setCumulativePrice(address _property, uint256 _value) external {
		// The previously used function
		// This function is only used in testing
		addressValidator().validateAddress(msg.sender, config().withdraw());

		eternalStorage().setUint(getCumulativePriceKey(_property), _value);
	}

	function getCumulativePrice(address _property)
		external
		view
		returns (uint256)
	{
		return eternalStorage().getUint(getCumulativePriceKey(_property));
	}

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

	// WithdrawalLimitTotal
	function setWithdrawalLimitTotal(
		address _property,
		address _user,
		uint256 _value
	) external {
		addressValidator().validateAddress(msg.sender, config().withdraw());

		eternalStorage().setUint(
			getWithdrawalLimitTotalKey(_property, _user),
			_value
		);
	}

	function getWithdrawalLimitTotal(address _property, address _user)
		external
		view
		returns (uint256)
	{
		return
			eternalStorage().getUint(
				getWithdrawalLimitTotalKey(_property, _user)
			);
	}

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

	// WithdrawalLimitBalance
	function setWithdrawalLimitBalance(
		address _property,
		address _user,
		uint256 _value
	) external {
		addressValidator().validateAddress(msg.sender, config().withdraw());

		eternalStorage().setUint(
			getWithdrawalLimitBalanceKey(_property, _user),
			_value
		);
	}

	function getWithdrawalLimitBalance(address _property, address _user)
		external
		view
		returns (uint256)
	{
		return
			eternalStorage().getUint(
				getWithdrawalLimitBalanceKey(_property, _user)
			);
	}

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

	//LastWithdrawalPrice
	function setLastWithdrawalPrice(
		address _property,
		address _user,
		uint256 _value
	) external {
		addressValidator().validateAddress(msg.sender, config().withdraw());

		eternalStorage().setUint(
			getLastWithdrawalPriceKey(_property, _user),
			_value
		);
	}

	function getLastWithdrawalPrice(address _property, address _user)
		external
		view
		returns (uint256)
	{
		return
			eternalStorage().getUint(
				getLastWithdrawalPriceKey(_property, _user)
			);
	}

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

	//PendingWithdrawal
	function setPendingWithdrawal(
		address _property,
		address _user,
		uint256 _value
	) external {
		addressValidator().validateAddress(msg.sender, config().withdraw());

		eternalStorage().setUint(
			getPendingWithdrawalKey(_property, _user),
			_value
		);
	}

	function getPendingWithdrawal(address _property, address _user)
		external
		view
		returns (uint256)
	{
		return
			eternalStorage().getUint(getPendingWithdrawalKey(_property, _user));
	}

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

	//LastCumulativeGlobalHoldersPrice
	function setLastCumulativeGlobalHoldersPrice(
		address _property,
		address _user,
		uint256 _value
	) external {
		addressValidator().validateAddress(msg.sender, config().withdraw());

		eternalStorage().setUint(
			getLastCumulativeGlobalHoldersPriceKey(_property, _user),
			_value
		);
	}

	function getLastCumulativeGlobalHoldersPrice(
		address _property,
		address _user
	) external view returns (uint256) {
		return
			eternalStorage().getUint(
				getLastCumulativeGlobalHoldersPriceKey(_property, _user)
			);
	}

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

// File: contracts/src/withdraw/IWithdraw.sol

pragma solidity ^0.5.0;

contract IWithdraw {
	function withdraw(address _property) external;

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

	function beforeBalanceChange(
		address _property,
		address _from,
		address _to
		// solium-disable-next-line indentation
	) external;

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

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

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

pragma solidity ^0.5.0;

contract ILockup {
	function lockup(
		address _from,
		address _property,
		uint256 _value
		// solium-disable-next-line indentation
	) external;

	function update() public;

	function cancel(address _property) external;

	function withdraw(address _property) external;

	function difference(address _property, uint256 _lastReward)
		public
		view
		returns (
			uint256 _reward,
			uint256 _holdersAmount,
			uint256 _holdersPrice,
			uint256 _interestAmount,
			uint256 _interestPrice
		);

	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
	)
		public
		view
		returns (
			// solium-disable-next-line indentation
			uint256
		);

	function withdrawInterest(address _property) external;
}

// File: contracts/src/metrics/IMetricsGroup.sol

pragma solidity ^0.5.0;

contract IMetricsGroup is IGroup {
	function removeGroup(address _addr) external;

	function totalIssuedMetrics() external view returns (uint256);

	function getMetricsCountPerProperty(address _property)
		public
		view
		returns (uint256);

	function hasAssets(address _property) public view returns (bool);
}

// File: contracts/src/withdraw/Withdraw.sol

pragma solidity ^0.5.0;

// prettier-ignore

/**
 * A contract that manages the withdrawal of holder rewards for Property holders.
 */
contract Withdraw is IWithdraw, UsingConfig, UsingValidator {
	using SafeMath for uint256;
	using Decimals for uint256;
	event PropertyTransfer(address _property, address _from, address _to);

	/**
	 * Initialize the passed address as AddressConfig address.
	 */
	// solium-disable-next-line no-empty-blocks
	constructor(address _config) public UsingConfig(_config) {}

	/**
	 * Withdraws rewards.
	 */
	function withdraw(address _property) external {
		/**
		 * Validates the passed Property address is included the Property address set.
		 */
		addressValidator().validateGroup(_property, config().propertyGroup());

		/**
		 * Gets the withdrawable rewards amount and the latest cumulative sum of the maximum mint amount.
		 */
		(uint256 value, uint256 lastPrice) = _calculateWithdrawableAmount(
			_property,
			msg.sender
		);

		/**
		 * Validates the result is not 0.
		 */
		require(value != 0, "withdraw value is 0");

		/**
		 * Saves the latest cumulative sum of the maximum mint amount.
		 * By subtracting this value when calculating the next rewards, always withdrawal the difference from the previous time.
		 */
		WithdrawStorage withdrawStorage = getStorage();
		withdrawStorage.setLastCumulativeGlobalHoldersPrice(
			_property,
			msg.sender,
			lastPrice
		);

		/**
		 * Sets the number of unwithdrawn rewards to 0.
		 */
		withdrawStorage.setPendingWithdrawal(_property, msg.sender, 0);

		/**
		 * Updates the withdrawal status to avoid double withdrawal for before DIP4.
		 */
		__updateLegacyWithdrawableAmount(_property, msg.sender);

		/**
		 * Mints the holder reward.
		 */
		ERC20Mintable erc20 = ERC20Mintable(config().token());
		require(erc20.mint(msg.sender, value), "dev mint failed");

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

		/**
		 * Adds the reward amount already withdrawn in the passed Property.
		 */
		withdrawStorage.setRewardsAmount(
			_property,
			withdrawStorage.getRewardsAmount(_property).add(value)
		);
	}

	/**
	 * Updates the change in compensation amount due to the change in the ownership ratio of the passed Property.
	 * When the ownership ratio of Property changes, the reward that the Property holder can withdraw will change.
	 * It is necessary to update the status before and after the ownership ratio changes.
	 */
	function beforeBalanceChange(
		address _property,
		address _from,
		address _to
	) external {
		/**
		 * Validates the sender is Allocator contract.
		 */
		addressValidator().validateAddress(msg.sender, config().allocator());

		WithdrawStorage withdrawStorage = getStorage();

		/**
		 * Gets the cumulative sum of the transfer source's "before transfer" withdrawable reward amount and the cumulative sum of the maximum mint amount.
		 */
		(uint256 amountFrom, uint256 priceFrom) = _calculateAmount(
			_property,
			_from
		);

		/**
		 * Gets the cumulative sum of the transfer destination's "before receive" withdrawable reward amount and the cumulative sum of the maximum mint amount.
		 */
		(uint256 amountTo, uint256 priceTo) = _calculateAmount(_property, _to);

		/**
		 * Updates the last cumulative sum of the maximum mint amount of the transfer source and destination.
		 */
		withdrawStorage.setLastCumulativeGlobalHoldersPrice(
			_property,
			_from,
			priceFrom
		);
		withdrawStorage.setLastCumulativeGlobalHoldersPrice(
			_property,
			_to,
			priceTo
		);

		/**
		 * Gets the unwithdrawn reward amount of the transfer source and destination.
		 */
		uint256 pendFrom = withdrawStorage.getPendingWithdrawal(
			_property,
			_from
		);
		uint256 pendTo = withdrawStorage.getPendingWithdrawal(_property, _to);

		/**
		 * Adds the undrawn reward amount of the transfer source and destination.
		 */
		withdrawStorage.setPendingWithdrawal(
			_property,
			_from,
			pendFrom.add(amountFrom)
		);
		withdrawStorage.setPendingWithdrawal(
			_property,
			_to,
			pendTo.add(amountTo)
		);

		emit PropertyTransfer(_property, _from, _to);
	}

	/**
	 * Returns the reward amount already withdrawn in the passed Property.
	 */
	function getRewardsAmount(address _property)
		external
		view
		returns (uint256)
	{
		return getStorage().getRewardsAmount(_property);
	}

	/**
	 * Passthrough to `Lockup.difference` function.
	 */
	function difference(
		WithdrawStorage withdrawStorage,
		address _property,
		address _user
	)
		private
		view
		returns (
			uint256 _reward,
			uint256 _holdersAmount,
			uint256 _holdersPrice,
			uint256 _interestAmount,
			uint256 _interestPrice
		)
	{
		/**
		 * Gets and passes the last recorded cumulative sum of the maximum mint amount.
		 */
		uint256 _last = withdrawStorage.getLastCumulativeGlobalHoldersPrice(
			_property,
			_user
		);
		return ILockup(config().lockup()).difference(_property, _last);
	}

	/**
	 * Returns the holder reward.
	 */
	function _calculateAmount(address _property, address _user)
		private
		view
		returns (uint256 _amount, uint256 _price)
	{
		WithdrawStorage withdrawStorage = getStorage();

		/**
		 * Gets the latest cumulative sum of the maximum mint amount,
		 * and the difference to the previous withdrawal of holder reward unit price.
		 */
		(uint256 reward, , uint256 _holdersPrice, , ) = difference(
			withdrawStorage,
			_property,
			_user
		);

		/**
		 * Gets the ownership ratio of the passed user and the Property.
		 */
		uint256 balance = ERC20Mintable(_property).balanceOf(_user);

		/**
		 * Multiplied by the number of tokens to the holder reward unit price.
		 */
		uint256 value = _holdersPrice.mul(balance);

		/**
		 * Returns the result after adjusted decimals to 10^18, and the latest cumulative sum of the maximum mint amount.
		 */
		return (value.divBasis().divBasis(), reward);
	}

	/**
	 * Returns the total rewards currently available for withdrawal. (For calling from inside the contract)
	 */
	function _calculateWithdrawableAmount(address _property, address _user)
		private
		view
		returns (uint256 _amount, uint256 _price)
	{
		/**
		 * Gets the latest withdrawal reward amount.
		 */
		(uint256 _value, uint256 price) = _calculateAmount(_property, _user);

		/**
		 * If the passed Property has not authenticated, returns always 0.
		 */
		if (
			IMetricsGroup(config().metricsGroup()).hasAssets(_property) == false
		) {
			return (0, price);
		}

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

		/**
		 * Gets the reward amount in saved without withdrawal and returns the sum of all values.
		 */
		uint256 value = _value
			.add(getStorage().getPendingWithdrawal(_property, _user))
			.add(legacy);
		return (value, price);
	}

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

	/**
	 * Returns the cumulative sum of the holder rewards of the passed Property.
	 */
	function calculateTotalWithdrawableAmount(address _property)
		external
		view
		returns (uint256)
	{
		(, uint256 _amount, , , ) = ILockup(config().lockup()).difference(
			_property,
			0
		);

		/**
		 * Adjusts decimals to 10^18 and returns the result.
		 */
		return _amount.divBasis().divBasis();
	}

	/**
	 * 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 balance of the user.
	 */
	function __legacyWithdrawableAmount(address _property, address _user)
		private
		view
		returns (uint256)
	{
		WithdrawStorage withdrawStorage = getStorage();
		uint256 _last = withdrawStorage.getLastWithdrawalPrice(
			_property,
			_user
		);
		uint256 price = withdrawStorage.getCumulativePrice(_property);
		uint256 priceGap = price.sub(_last);
		uint256 balance = ERC20Mintable(_property).balanceOf(_user);
		uint256 value = priceGap.mul(balance);
		return value.divBasis();
	}

	/**
	 * Updates and treats the reward of before DIP4 as already received.
	 */
	function __updateLegacyWithdrawableAmount(address _property, address _user)
		private
	{
		WithdrawStorage withdrawStorage = getStorage();
		uint256 price = withdrawStorage.getCumulativePrice(_property);
		withdrawStorage.setLastWithdrawalPrice(_property, _user, price);
	}

	/**
	 * Returns WithdrawStorage instance.
	 */
	function getStorage() private view returns (WithdrawStorage) {
		return WithdrawStorage(config().withdrawStorage());
	}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_config","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_property","type":"address"},{"indexed":false,"internalType":"address","name":"_from","type":"address"},{"indexed":false,"internalType":"address","name":"_to","type":"address"}],"name":"PropertyTransfer","type":"event"},{"constant":false,"inputs":[{"internalType":"address","name":"_property","type":"address"},{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"}],"name":"beforeBalanceChange","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_property","type":"address"}],"name":"calculateTotalWithdrawableAmount","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":"calculateWithdrawableAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"configAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_property","type":"address"}],"name":"getRewardsAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_property","type":"address"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b50604051611f57380380611f578339818101604052602081101561003357600080fd5b5051600080546001600160a01b0319166001600160a01b03831617905560405161005c9061009f565b604051809103906000f080158015610078573d6000803e3d6000fd5b50600180546001600160a01b0319166001600160a01b0392909216919091179055506100ac565b61072b8061182c83390190565b611771806100bb6000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c80630448a8e614610067578063389435e8146100a157806351cff8d9146100d957806368f1b7c7146100ff578063d6c318711461012d578063dbe9345114610151575b600080fd5b61009f6004803603606081101561007d57600080fd5b506001600160a01b038135811691602081013582169160409091013516610177565b005b6100c7600480360360208110156100b757600080fd5b50356001600160a01b031661060e565b60408051918252519081900360200190f35b61009f600480360360208110156100ef57600080fd5b50356001600160a01b0316610717565b6100c76004803603604081101561011557600080fd5b506001600160a01b0381358116916020013516610c5d565b610135610c75565b604080516001600160a01b039092168252519081900360200190f35b6100c76004803603602081101561016757600080fd5b50356001600160a01b0316610c84565b61017f610d15565b6001600160a01b03166349616d7933610196610c75565b6001600160a01b031663aa5dcecc6040518163ffffffff1660e01b815260040160206040518083038186803b1580156101ce57600080fd5b505afa1580156101e2573d6000803e3d6000fd5b505050506040513d60208110156101f857600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b039384166004820152929091166024830152516044808301926000929190829003018186803b15801561024857600080fd5b505afa15801561025c573d6000803e3d6000fd5b50505050600061026a610d24565b90506000806102798686610d97565b9150915060008061028a8887610d97565b60408051637a334a7360e11b81526001600160a01b038c811660048301528b8116602483015260448201889052915193955091935087169163f46694e69160648082019260009290919082900301818387803b1580156102e957600080fd5b505af11580156102fd573d6000803e3d6000fd5b505060408051637a334a7360e11b81526001600160a01b038c811660048301528a81166024830152604482018690529151918916935063f46694e6925060648082019260009290919082900301818387803b15801561035b57600080fd5b505af115801561036f573d6000803e3d6000fd5b505060408051635699c7b160e01b81526001600160a01b038c811660048301528b811660248301529151600094509189169250635699c7b1916044808301926020929190829003018186803b1580156103c757600080fd5b505afa1580156103db573d6000803e3d6000fd5b505050506040513d60208110156103f157600080fd5b505160408051635699c7b160e01b81526001600160a01b038c811660048301528a81166024830152915192935060009291891691635699c7b191604480820192602092909190829003018186803b15801561044b57600080fd5b505afa15801561045f573d6000803e3d6000fd5b505050506040513d602081101561047557600080fd5b505190506001600160a01b03871663dcaf498e8b8b61049a868b63ffffffff610e7216565b6040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050600060405180830381600087803b15801561050257600080fd5b505af1158015610516573d6000803e3d6000fd5b5050506001600160a01b038816905063dcaf498e8b8a6105368589610e72565b6040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050600060405180830381600087803b15801561059e57600080fd5b505af11580156105b2573d6000803e3d6000fd5b5050604080516001600160a01b03808f168252808e1660208301528c168183015290517f7266de4b1e3ac6803b7f817fca44bef48f3eba3d105c3ebe0bba1f6bc6965f2f9350908190036060019150a150505050505050505050565b600080610619610c75565b6001600160a01b03166306490f476040518163ffffffff1660e01b815260040160206040518083038186803b15801561065157600080fd5b505afa158015610665573d6000803e3d6000fd5b505050506040513d602081101561067b57600080fd5b505160408051630a37f70760e21b81526001600160a01b03868116600483015260006024830152915191909216916328dfdc1c9160448083019260a0929190829003018186803b1580156106ce57600080fd5b505afa1580156106e2573d6000803e3d6000fd5b505050506040513d60a08110156106f857600080fd5b5060200151905061071061070b82610ecc565b610ecc565b9392505050565b61071f610d15565b6001600160a01b031663d16ff47082610736610c75565b6001600160a01b031663ffeed7a96040518163ffffffff1660e01b815260040160206040518083038186803b15801561076e57600080fd5b505afa158015610782573d6000803e3d6000fd5b505050506040513d602081101561079857600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b039384166004820152929091166024830152516044808301926000929190829003018186803b1580156107e857600080fd5b505afa1580156107fc573d6000803e3d6000fd5b5050505060008061080d8333610ee6565b91509150816000141561085d576040805162461bcd60e51b8152602060048201526013602482015272077697468647261772076616c7565206973203606c1b604482015290519081900360640190fd5b6000610867610d24565b60408051637a334a7360e11b81526001600160a01b0387811660048301523360248301526044820186905291519293509083169163f46694e69160648082019260009290919082900301818387803b1580156108c257600080fd5b505af11580156108d6573d6000803e3d6000fd5b505060408051636e57a4c760e11b81526001600160a01b0388811660048301523360248301526000604483018190529251908616945063dcaf498e93506064808301939282900301818387803b15801561092f57600080fd5b505af1158015610943573d6000803e3d6000fd5b5050505061095184336110b2565b600061095b610c75565b6001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561099357600080fd5b505afa1580156109a7573d6000803e3d6000fd5b505050506040513d60208110156109bd57600080fd5b5051604080516340c10f1960e01b81523360048201526024810187905290519192506001600160a01b038316916340c10f19916044808201926020929091908290030181600087803b158015610a1257600080fd5b505af1158015610a26573d6000803e3d6000fd5b505050506040513d6020811015610a3c57600080fd5b5051610a81576040805162461bcd60e51b815260206004820152600f60248201526e19195d881b5a5b9d0819985a5b1959608a1b604482015290519081900360640190fd5b6000610a8b610c75565b6001600160a01b03166306490f476040518163ffffffff1660e01b815260040160206040518083038186803b158015610ac357600080fd5b505afa158015610ad7573d6000803e3d6000fd5b505050506040513d6020811015610aed57600080fd5b50516040805163a2e6204560e01b815290519192506001600160a01b0383169163a2e620459160048082019260009290919082900301818387803b158015610b3457600080fd5b505af1158015610b48573d6000803e3d6000fd5b50505050826001600160a01b0316630630ba6887610bee88876001600160a01b031663dbe934518c6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610bb657600080fd5b505afa158015610bca573d6000803e3d6000fd5b505050506040513d6020811015610be057600080fd5b50519063ffffffff610e7216565b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015610c3d57600080fd5b505af1158015610c51573d6000803e3d6000fd5b50505050505050505050565b600080610c6a8484610ee6565b509150505b92915050565b6000546001600160a01b031690565b6000610c8e610d24565b6001600160a01b031663dbe93451836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610ce357600080fd5b505afa158015610cf7573d6000803e3d6000fd5b505050506040513d6020811015610d0d57600080fd5b505192915050565b6001546001600160a01b031690565b6000610d2e610c75565b6001600160a01b031663fa651cdf6040518163ffffffff1660e01b815260040160206040518083038186803b158015610d6657600080fd5b505afa158015610d7a573d6000803e3d6000fd5b505050506040513d6020811015610d9057600080fd5b5051905090565b6000806000610da4610d24565b9050600080610db48388886111bd565b505092505091506000876001600160a01b03166370a08231886040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610e1357600080fd5b505afa158015610e27573d6000803e3d6000fd5b505050506040513d6020811015610e3d57600080fd5b505190506000610e53838363ffffffff61137716565b9050610e6161070b82610ecc565b9650929450505050505b9250929050565b600082820183811015610710576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000610c6f82670de0b6b3a764000063ffffffff6113d016565b600080600080610ef68686610d97565b91509150610f02610c75565b6001600160a01b031663628f043d6040518163ffffffff1660e01b815260040160206040518083038186803b158015610f3a57600080fd5b505afa158015610f4e573d6000803e3d6000fd5b505050506040513d6020811015610f6457600080fd5b505160408051638b234cb160e01b81526001600160a01b03898116600483015291519190921691638b234cb1916024808301926020929190829003018186803b158015610fb057600080fd5b505afa158015610fc4573d6000803e3d6000fd5b505050506040513d6020811015610fda57600080fd5b5051610fed57600093509150610e6b9050565b6000610ff98787611412565b905060006110a48261109861100c610d24565b60408051635699c7b160e01b81526001600160a01b038e811660048301528d8116602483015291519290911691635699c7b191604480820192602092909190829003018186803b15801561105f57600080fd5b505afa158015611073573d6000803e3d6000fd5b505050506040513d602081101561108957600080fd5b5051879063ffffffff610e7216565b9063ffffffff610e7216565b989297509195505050505050565b60006110bc610d24565b90506000816001600160a01b0316631382da2c856040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561111657600080fd5b505afa15801561112a573d6000803e3d6000fd5b505050506040513d602081101561114057600080fd5b50516040805163020ed06960e61b81526001600160a01b0387811660048301528681166024830152604482018490529151929350908416916383b41a409160648082019260009290919082900301818387803b15801561119f57600080fd5b505af11580156111b3573d6000803e3d6000fd5b5050505050505050565b600080600080600080886001600160a01b031663d5d6be0489896040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b031681526020019250505060206040518083038186803b15801561123657600080fd5b505afa15801561124a573d6000803e3d6000fd5b505050506040513d602081101561126057600080fd5b5051905061126c610c75565b6001600160a01b03166306490f476040518163ffffffff1660e01b815260040160206040518083038186803b1580156112a457600080fd5b505afa1580156112b8573d6000803e3d6000fd5b505050506040513d60208110156112ce57600080fd5b505160408051630a37f70760e21b81526001600160a01b038b8116600483015260248201859052915191909216916328dfdc1c9160448083019260a0929190829003018186803b15801561132157600080fd5b505afa158015611335573d6000803e3d6000fd5b505050506040513d60a081101561134b57600080fd5b508051602082015160408301516060840151608090940151929d919c509a509198509650945050505050565b60008261138657506000610c6f565b8282028284828161139357fe5b04146107105760405162461bcd60e51b815260040180806020018281038252602181526020018061171c6021913960400191505060405180910390fd5b600061071083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506115e2565b60008061141d610d24565b6040805162d545a960e31b81526001600160a01b03878116600483015286811660248301529151929350600092918416916306aa2d4891604480820192602092909190829003018186803b15801561147457600080fd5b505afa158015611488573d6000803e3d6000fd5b505050506040513d602081101561149e57600080fd5b5051604080516304e0b68b60e21b81526001600160a01b038881166004830152915192935060009291851691631382da2c91602480820192602092909190829003018186803b1580156114f057600080fd5b505afa158015611504573d6000803e3d6000fd5b505050506040513d602081101561151a57600080fd5b505190506000611530828463ffffffff61168416565b90506000876001600160a01b03166370a08231886040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561158a57600080fd5b505afa15801561159e573d6000803e3d6000fd5b505050506040513d60208110156115b457600080fd5b5051905060006115ca838363ffffffff61137716565b90506115d581610ecc565b9998505050505050505050565b6000818361166e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561163357818101518382015260200161161b565b50505050905090810190601f1680156116605780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161167a57fe5b0495945050505050565b600061071083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250600081848411156117135760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561163357818101518382015260200161161b565b50505090039056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a265627a7a72315820345571285a67ae354deee92afe9cf0fb41624abba52521077964963a2f1494ce64736f6c63430005110032608060405234801561001057600080fd5b5061070b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c80631bde7d8f1461006757806349616d79146100a75780636dd893b9146100d5578063a21929631461010d578063b292b54914610145578063d16ff4701461016b575b600080fd5b6100a56004803603608081101561007d57600080fd5b506001600160a01b038135811691602081013582169160408201358116916060013516610199565b005b6100a5600480360360408110156100bd57600080fd5b506001600160a01b03813581169160200135166102a1565b6100a5600480360360608110156100eb57600080fd5b506001600160a01b03813581169160208101358216916040909101351661032b565b6100a56004803603606081101561012357600080fd5b506001600160a01b0381358116916020810135821691604090910135166103cf565b6100a56004803603602081101561015b57600080fd5b50356001600160a01b031661054b565b6100a56004803603604081101561018157600080fd5b506001600160a01b03813581169160200135166105c6565b826001600160a01b0316846001600160a01b031614156101b85761029b565b816001600160a01b0316846001600160a01b031614156101d75761029b565b806001600160a01b0316846001600160a01b0316146040518060400160405280601781526020016000805160206106b7833981519152815250906102995760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561025e578181015183820152602001610246565b50505050905090810190601f16801561028b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505b50505050565b806001600160a01b0316826001600160a01b0316146040518060400160405280601781526020016000805160206106b7833981519152815250906103265760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561025e578181015183820152602001610246565b505050565b816001600160a01b0316836001600160a01b0316141561034a57610326565b806001600160a01b0316836001600160a01b0316146040518060400160405280601781526020016000805160206106b78339815191528152509061029b5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561025e578181015183820152602001610246565b816001600160a01b0316639e0cc3c4846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561042557600080fd5b505afa158015610439573d6000803e3d6000fd5b505050506040513d602081101561044f57600080fd5b50511561045b57610326565b806001600160a01b0316639e0cc3c4846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156104b157600080fd5b505afa1580156104c5573d6000803e3d6000fd5b505050506040513d60208110156104db57600080fd5b505160408051808201909152601781526000805160206106b783398151915260208201529061029b5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561025e578181015183820152602001610246565b60408051808201909152601781526000805160206106b783398151915260208201526001600160a01b0382166105c25760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561025e578181015183820152602001610246565b5050565b806001600160a01b0316639e0cc3c4836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561061c57600080fd5b505afa158015610630573d6000803e3d6000fd5b505050506040513d602081101561064657600080fd5b505160408051808201909152601781526000805160206106b78339815191526020820152906103265760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561025e57818101518382015260200161024656fe7468697320697320696c6c6567616c2061646472657373000000000000000000a265627a7a72315820667b5de3a803aaac8684108683c8810e13256a965db08b51f2f62d7cb8b8b15364736f6c634300051100320000000000000000000000001d415aa39d647834786eb9b5a333a50e9935b796

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100625760003560e01c80630448a8e614610067578063389435e8146100a157806351cff8d9146100d957806368f1b7c7146100ff578063d6c318711461012d578063dbe9345114610151575b600080fd5b61009f6004803603606081101561007d57600080fd5b506001600160a01b038135811691602081013582169160409091013516610177565b005b6100c7600480360360208110156100b757600080fd5b50356001600160a01b031661060e565b60408051918252519081900360200190f35b61009f600480360360208110156100ef57600080fd5b50356001600160a01b0316610717565b6100c76004803603604081101561011557600080fd5b506001600160a01b0381358116916020013516610c5d565b610135610c75565b604080516001600160a01b039092168252519081900360200190f35b6100c76004803603602081101561016757600080fd5b50356001600160a01b0316610c84565b61017f610d15565b6001600160a01b03166349616d7933610196610c75565b6001600160a01b031663aa5dcecc6040518163ffffffff1660e01b815260040160206040518083038186803b1580156101ce57600080fd5b505afa1580156101e2573d6000803e3d6000fd5b505050506040513d60208110156101f857600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b039384166004820152929091166024830152516044808301926000929190829003018186803b15801561024857600080fd5b505afa15801561025c573d6000803e3d6000fd5b50505050600061026a610d24565b90506000806102798686610d97565b9150915060008061028a8887610d97565b60408051637a334a7360e11b81526001600160a01b038c811660048301528b8116602483015260448201889052915193955091935087169163f46694e69160648082019260009290919082900301818387803b1580156102e957600080fd5b505af11580156102fd573d6000803e3d6000fd5b505060408051637a334a7360e11b81526001600160a01b038c811660048301528a81166024830152604482018690529151918916935063f46694e6925060648082019260009290919082900301818387803b15801561035b57600080fd5b505af115801561036f573d6000803e3d6000fd5b505060408051635699c7b160e01b81526001600160a01b038c811660048301528b811660248301529151600094509189169250635699c7b1916044808301926020929190829003018186803b1580156103c757600080fd5b505afa1580156103db573d6000803e3d6000fd5b505050506040513d60208110156103f157600080fd5b505160408051635699c7b160e01b81526001600160a01b038c811660048301528a81166024830152915192935060009291891691635699c7b191604480820192602092909190829003018186803b15801561044b57600080fd5b505afa15801561045f573d6000803e3d6000fd5b505050506040513d602081101561047557600080fd5b505190506001600160a01b03871663dcaf498e8b8b61049a868b63ffffffff610e7216565b6040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050600060405180830381600087803b15801561050257600080fd5b505af1158015610516573d6000803e3d6000fd5b5050506001600160a01b038816905063dcaf498e8b8a6105368589610e72565b6040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050600060405180830381600087803b15801561059e57600080fd5b505af11580156105b2573d6000803e3d6000fd5b5050604080516001600160a01b03808f168252808e1660208301528c168183015290517f7266de4b1e3ac6803b7f817fca44bef48f3eba3d105c3ebe0bba1f6bc6965f2f9350908190036060019150a150505050505050505050565b600080610619610c75565b6001600160a01b03166306490f476040518163ffffffff1660e01b815260040160206040518083038186803b15801561065157600080fd5b505afa158015610665573d6000803e3d6000fd5b505050506040513d602081101561067b57600080fd5b505160408051630a37f70760e21b81526001600160a01b03868116600483015260006024830152915191909216916328dfdc1c9160448083019260a0929190829003018186803b1580156106ce57600080fd5b505afa1580156106e2573d6000803e3d6000fd5b505050506040513d60a08110156106f857600080fd5b5060200151905061071061070b82610ecc565b610ecc565b9392505050565b61071f610d15565b6001600160a01b031663d16ff47082610736610c75565b6001600160a01b031663ffeed7a96040518163ffffffff1660e01b815260040160206040518083038186803b15801561076e57600080fd5b505afa158015610782573d6000803e3d6000fd5b505050506040513d602081101561079857600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b039384166004820152929091166024830152516044808301926000929190829003018186803b1580156107e857600080fd5b505afa1580156107fc573d6000803e3d6000fd5b5050505060008061080d8333610ee6565b91509150816000141561085d576040805162461bcd60e51b8152602060048201526013602482015272077697468647261772076616c7565206973203606c1b604482015290519081900360640190fd5b6000610867610d24565b60408051637a334a7360e11b81526001600160a01b0387811660048301523360248301526044820186905291519293509083169163f46694e69160648082019260009290919082900301818387803b1580156108c257600080fd5b505af11580156108d6573d6000803e3d6000fd5b505060408051636e57a4c760e11b81526001600160a01b0388811660048301523360248301526000604483018190529251908616945063dcaf498e93506064808301939282900301818387803b15801561092f57600080fd5b505af1158015610943573d6000803e3d6000fd5b5050505061095184336110b2565b600061095b610c75565b6001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561099357600080fd5b505afa1580156109a7573d6000803e3d6000fd5b505050506040513d60208110156109bd57600080fd5b5051604080516340c10f1960e01b81523360048201526024810187905290519192506001600160a01b038316916340c10f19916044808201926020929091908290030181600087803b158015610a1257600080fd5b505af1158015610a26573d6000803e3d6000fd5b505050506040513d6020811015610a3c57600080fd5b5051610a81576040805162461bcd60e51b815260206004820152600f60248201526e19195d881b5a5b9d0819985a5b1959608a1b604482015290519081900360640190fd5b6000610a8b610c75565b6001600160a01b03166306490f476040518163ffffffff1660e01b815260040160206040518083038186803b158015610ac357600080fd5b505afa158015610ad7573d6000803e3d6000fd5b505050506040513d6020811015610aed57600080fd5b50516040805163a2e6204560e01b815290519192506001600160a01b0383169163a2e620459160048082019260009290919082900301818387803b158015610b3457600080fd5b505af1158015610b48573d6000803e3d6000fd5b50505050826001600160a01b0316630630ba6887610bee88876001600160a01b031663dbe934518c6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610bb657600080fd5b505afa158015610bca573d6000803e3d6000fd5b505050506040513d6020811015610be057600080fd5b50519063ffffffff610e7216565b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015610c3d57600080fd5b505af1158015610c51573d6000803e3d6000fd5b50505050505050505050565b600080610c6a8484610ee6565b509150505b92915050565b6000546001600160a01b031690565b6000610c8e610d24565b6001600160a01b031663dbe93451836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610ce357600080fd5b505afa158015610cf7573d6000803e3d6000fd5b505050506040513d6020811015610d0d57600080fd5b505192915050565b6001546001600160a01b031690565b6000610d2e610c75565b6001600160a01b031663fa651cdf6040518163ffffffff1660e01b815260040160206040518083038186803b158015610d6657600080fd5b505afa158015610d7a573d6000803e3d6000fd5b505050506040513d6020811015610d9057600080fd5b5051905090565b6000806000610da4610d24565b9050600080610db48388886111bd565b505092505091506000876001600160a01b03166370a08231886040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610e1357600080fd5b505afa158015610e27573d6000803e3d6000fd5b505050506040513d6020811015610e3d57600080fd5b505190506000610e53838363ffffffff61137716565b9050610e6161070b82610ecc565b9650929450505050505b9250929050565b600082820183811015610710576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000610c6f82670de0b6b3a764000063ffffffff6113d016565b600080600080610ef68686610d97565b91509150610f02610c75565b6001600160a01b031663628f043d6040518163ffffffff1660e01b815260040160206040518083038186803b158015610f3a57600080fd5b505afa158015610f4e573d6000803e3d6000fd5b505050506040513d6020811015610f6457600080fd5b505160408051638b234cb160e01b81526001600160a01b03898116600483015291519190921691638b234cb1916024808301926020929190829003018186803b158015610fb057600080fd5b505afa158015610fc4573d6000803e3d6000fd5b505050506040513d6020811015610fda57600080fd5b5051610fed57600093509150610e6b9050565b6000610ff98787611412565b905060006110a48261109861100c610d24565b60408051635699c7b160e01b81526001600160a01b038e811660048301528d8116602483015291519290911691635699c7b191604480820192602092909190829003018186803b15801561105f57600080fd5b505afa158015611073573d6000803e3d6000fd5b505050506040513d602081101561108957600080fd5b5051879063ffffffff610e7216565b9063ffffffff610e7216565b989297509195505050505050565b60006110bc610d24565b90506000816001600160a01b0316631382da2c856040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561111657600080fd5b505afa15801561112a573d6000803e3d6000fd5b505050506040513d602081101561114057600080fd5b50516040805163020ed06960e61b81526001600160a01b0387811660048301528681166024830152604482018490529151929350908416916383b41a409160648082019260009290919082900301818387803b15801561119f57600080fd5b505af11580156111b3573d6000803e3d6000fd5b5050505050505050565b600080600080600080886001600160a01b031663d5d6be0489896040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b031681526020019250505060206040518083038186803b15801561123657600080fd5b505afa15801561124a573d6000803e3d6000fd5b505050506040513d602081101561126057600080fd5b5051905061126c610c75565b6001600160a01b03166306490f476040518163ffffffff1660e01b815260040160206040518083038186803b1580156112a457600080fd5b505afa1580156112b8573d6000803e3d6000fd5b505050506040513d60208110156112ce57600080fd5b505160408051630a37f70760e21b81526001600160a01b038b8116600483015260248201859052915191909216916328dfdc1c9160448083019260a0929190829003018186803b15801561132157600080fd5b505afa158015611335573d6000803e3d6000fd5b505050506040513d60a081101561134b57600080fd5b508051602082015160408301516060840151608090940151929d919c509a509198509650945050505050565b60008261138657506000610c6f565b8282028284828161139357fe5b04146107105760405162461bcd60e51b815260040180806020018281038252602181526020018061171c6021913960400191505060405180910390fd5b600061071083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506115e2565b60008061141d610d24565b6040805162d545a960e31b81526001600160a01b03878116600483015286811660248301529151929350600092918416916306aa2d4891604480820192602092909190829003018186803b15801561147457600080fd5b505afa158015611488573d6000803e3d6000fd5b505050506040513d602081101561149e57600080fd5b5051604080516304e0b68b60e21b81526001600160a01b038881166004830152915192935060009291851691631382da2c91602480820192602092909190829003018186803b1580156114f057600080fd5b505afa158015611504573d6000803e3d6000fd5b505050506040513d602081101561151a57600080fd5b505190506000611530828463ffffffff61168416565b90506000876001600160a01b03166370a08231886040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561158a57600080fd5b505afa15801561159e573d6000803e3d6000fd5b505050506040513d60208110156115b457600080fd5b5051905060006115ca838363ffffffff61137716565b90506115d581610ecc565b9998505050505050505050565b6000818361166e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561163357818101518382015260200161161b565b50505050905090810190601f1680156116605780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161167a57fe5b0495945050505050565b600061071083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250600081848411156117135760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561163357818101518382015260200161161b565b50505090039056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a265627a7a72315820345571285a67ae354deee92afe9cf0fb41624abba52521077964963a2f1494ce64736f6c63430005110032

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

0000000000000000000000001d415aa39d647834786eb9b5a333a50e9935b796

-----Decoded View---------------
Arg [0] : _config (address): 0x1D415aa39D647834786EB9B5a333A50e9935b796

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000001d415aa39d647834786eb9b5a333a50e9935b796


Deployed Bytecode Sourcemap

46771:9081:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;46771:9081:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49264:1725;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;49264:1725:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;54209:319;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;54209:319:0;-1:-1:-1;;;;;54209:319:0;;:::i;:::-;;;;;;;;;;;;;;;;47189:1745;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;47189:1745:0;-1:-1:-1;;;;;47189:1745:0;;:::i;53907:207::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;53907:207:0;;;;;;;;;;:::i;32441:90::-;;;:::i;:::-;;;;-1:-1:-1;;;;;32441:90:0;;;;;;;;;;;;;;51079:145;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;51079:145:0;-1:-1:-1;;;;;51079:145:0;;:::i;49264:1725::-;49431:18;:16;:18::i;:::-;-1:-1:-1;;;;;49431:34:0;;49466:10;49478:8;:6;:8::i;:::-;-1:-1:-1;;;;;49478:18:0;;:20;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;49478:20:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;49478:20:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;49478:20:0;49431:68;;;-1:-1:-1;;;;;;49431:68:0;;;;;;;-1:-1:-1;;;;;49431:68:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;49431:68:0;;;;;;;;;;;5:2:-1;;;;30:1;27;20:12;5:2;49431:68:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;49431:68:0;;;;49506:31;49540:12;:10;:12::i;:::-;49506:46;;49725:18;49745:17;49766:47;49788:9;49803:5;49766:16;:47::i;:::-;49724:89;;;;49990:16;50008:15;50027:32;50044:9;50055:3;50027:16;:32::i;:::-;50185:97;;;-1:-1:-1;;;50185:97:0;;-1:-1:-1;;;;;50185:97:0;;;;;;;;;;;;;;;;;;;;;;49989:70;;-1:-1:-1;49989:70:0;;-1:-1:-1;50185:51:0;;;;;:97;;;;;-1:-1:-1;;50185:97:0;;;;;;;;-1:-1:-1;50185:51:0;:97;;;5:2:-1;;;;30:1;27;20:12;5:2;50185:97:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;50287:93:0;;;-1:-1:-1;;;50287:93:0;;-1:-1:-1;;;;;50287:93:0;;;;;;;;;;;;;;;;;;;;;;:51;;;;-1:-1:-1;50287:51:0;;-1:-1:-1;50287:93:0;;;;;-1:-1:-1;;50287:93:0;;;;;;;;-1:-1:-1;50287:51:0;:93;;;5:2:-1;;;;30:1;27;20:12;5:2;50287:93:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;50501:67:0;;;-1:-1:-1;;;50501:67:0;;-1:-1:-1;;;;;50501:67:0;;;;;;;;;;;;;;;;50482:16;;-1:-1:-1;50501:36:0;;;;-1:-1:-1;50501:36:0;;:67;;;;;;;;;;;;;;:36;:67;;;5:2:-1;;;;30:1;27;20:12;5:2;50501:67:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;50501:67:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;50501:67:0;50590:52;;;-1:-1:-1;;;50590:52:0;;-1:-1:-1;;;;;50590:52:0;;;;;;;;;;;;;;;;50501:67;;-1:-1:-1;50573:14:0;;50590:36;;;;;;:52;;;;;50501:67;;50590:52;;;;;;;;:36;:52;;;5:2:-1;;;;30:1;27;20:12;5:2;50590:52:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;50590:52:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;50590:52:0;;-1:-1:-1;;;;;;50740:36:0;;;50782:9;50797:5;50808:24;:8;50821:10;50808:24;:12;:24;:::i;:::-;50740:97;;;;;;;;;;;;;-1:-1:-1;;;;;50740:97:0;-1:-1:-1;;;;;50740:97:0;;;;;;-1:-1:-1;;;;;50740:97:0;-1:-1:-1;;;;;50740:97:0;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;50740:97:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;;;;;;;50842:36:0;;;-1:-1:-1;50842:36:0;50884:9;50899:3;50908:20;:6;50919:8;50908:10;:20::i;:::-;50842:91;;;;;;;;;;;;;-1:-1:-1;;;;;50842:91:0;-1:-1:-1;;;;;50842:91:0;;;;;;-1:-1:-1;;;;;50842:91:0;-1:-1:-1;;;;;50842:91:0;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;50842:91:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;50945:39:0;;;-1:-1:-1;;;;;50945:39:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;50945:39:0;;;;;;;-1:-1:-1;50945:39:0;49264:1725;;;;;;;;;;:::o;54209:319::-;54302:7;54321:15;54354:8;:6;:8::i;:::-;-1:-1:-1;;;;;54354:15:0;;:17;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;54354:17:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;54354:17:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;54354:17:0;54346:64;;;-1:-1:-1;;;54346:64:0;;-1:-1:-1;;;;;54346:64:0;;;;;;;54404:1;54346:64;;;;;;:37;;;;;;;:64;;;;;;;;;;;;;;:37;:64;;;5:2:-1;;;;30:1;27;20:12;5:2;54346:64:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;54346:64:0;;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;54346:64:0;;;;-1:-1:-1;54494:29:0;:18;54346:64;54494:16;:18::i;:::-;:27;:29::i;:::-;54487:36;54209:319;-1:-1:-1;;;54209:319:0:o;47189:1745::-;47336:18;:16;:18::i;:::-;-1:-1:-1;;;;;47336:32:0;;47369:9;47380:8;:6;:8::i;:::-;-1:-1:-1;;;;;47380:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;47380:24:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;47380:24:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;47380:24:0;47336:69;;;-1:-1:-1;;;;;;47336:69:0;;;;;;;-1:-1:-1;;;;;47336:69:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;47336:69:0;;;;;;;;;;;5:2:-1;;;;30:1;27;20:12;5:2;47336:69:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;47336:69:0;;;;47528:13;47543:17;47564:64;47598:9;47613:10;47564:28;:64::i;:::-;47527:101;;;;47694:5;47703:1;47694:10;;47686:42;;;;;-1:-1:-1;;;47686:42:0;;;;;;;;;;;;-1:-1:-1;;;47686:42:0;;;;;;;;;;;;;;;47939:31;47973:12;:10;:12::i;:::-;47990:102;;;-1:-1:-1;;;47990:102:0;;-1:-1:-1;;;;;47990:102:0;;;;;;;48062:10;47990:102;;;;;;;;;;;;47939:46;;-1:-1:-1;47990:51:0;;;;;;:102;;;;;-1:-1:-1;;47990:102:0;;;;;;;;-1:-1:-1;47990:51:0;:102;;;5:2:-1;;;;30:1;27;20:12;5:2;47990:102:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;48164:62:0;;;-1:-1:-1;;;48164:62:0;;-1:-1:-1;;;;;48164:62:0;;;;;;;48212:10;48164:62;;;;48224:1;48164:62;;;;;;;;:36;;;;-1:-1:-1;48164:36:0;;-1:-1:-1;48164:62:0;;;;;48224:1;48164:62;;;;;48224:1;48164:36;:62;;;5:2:-1;;;;30:1;27;20:12;5:2;48164:62:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;48164:62:0;;;;48327:55;48360:9;48371:10;48327:32;:55::i;:::-;48434:19;48470:8;:6;:8::i;:::-;-1:-1:-1;;;;;48470:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48470:16:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;48470:16:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;48470:16:0;48500:29;;;-1:-1:-1;;;48500:29:0;;48511:10;48500:29;;;;;;;;;;;;48470:16;;-1:-1:-1;;;;;;48500:10:0;;;;;:29;;;;;48470:16;;48500:29;;;;;;;;-1:-1:-1;48500:10:0;:29;;;5:2:-1;;;;30:1;27;20:12;5:2;48500:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;48500:29:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;48500:29:0;48492:57;;;;;-1:-1:-1;;;48492:57:0;;;;;;;;;;;;-1:-1:-1;;;48492:57:0;;;;;;;;;;;;;;;48662:14;48687:8;:6;:8::i;:::-;-1:-1:-1;;;;;48687:15:0;;:17;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48687:17:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;48687:17:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;48687:17:0;48710:15;;;-1:-1:-1;;;48710:15:0;;;;48687:17;;-1:-1:-1;;;;;;48710:13:0;;;;;:15;;;;;;;;;;;;;;;;:13;:15;;;5:2:-1;;;;30:1;27;20:12;5:2;48710:15:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;48710:15:0;;;;48817;-1:-1:-1;;;;;48817:32:0;;48855:9;48870:54;48918:5;48870:15;-1:-1:-1;;;;;48870:32:0;;48903:9;48870:43;;;;;;;;;;;;;-1:-1:-1;;;;;48870:43:0;-1:-1:-1;;;;;48870:43:0;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48870:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;48870:43:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;48870:43:0;;:54;:47;:54;:::i;:::-;48817:112;;;;;;;;;;;;;-1:-1:-1;;;;;48817:112:0;-1:-1:-1;;;;;48817:112:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48817:112:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;48817:112:0;;;;47189:1745;;;;;;:::o;53907:207::-;54010:7;54027:13;54046:46;54075:9;54086:5;54046:28;:46::i;:::-;-1:-1:-1;54026:66:0;-1:-1:-1;;53907:207:0;;;;;:::o;32441:90::-;32489:7;32518;-1:-1:-1;;;;;32518:7:0;32441:90;:::o;51079:145::-;51156:7;51179:12;:10;:12::i;:::-;-1:-1:-1;;;;;51179:29:0;;51209:9;51179:40;;;;;;;;;;;;;-1:-1:-1;;;;;51179:40:0;-1:-1:-1;;;;;51179:40:0;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51179:40:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;51179:40:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;51179:40:0;;51079:145;-1:-1:-1;;51079:145:0:o;25994:96::-;26075:10;;-1:-1:-1;;;;;26075:10:0;25994:96;:::o;55728:121::-;55772:15;55817:8;:6;:8::i;:::-;-1:-1:-1;;;;;55817:24:0;;:26;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;55817:26:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;55817:26:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;55817:26:0;;-1:-1:-1;55728:121:0;:::o;51883:926::-;51974:15;51991:14;52014:31;52048:12;:10;:12::i;:::-;52014:46;;52228:14;52246:21;52275:62;52291:15;52312:9;52327:5;52275:10;:62::i;:::-;52227:110;;;;;;;52426:15;52458:9;-1:-1:-1;;;;;52444:34:0;;52479:5;52444:41;;;;;;;;;;;;;-1:-1:-1;;;;;52444:41:0;-1:-1:-1;;;;;52444:41:0;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52444:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;52444:41:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;52444:41:0;;-1:-1:-1;52580:13:0;52596:26;:13;52444:41;52596:26;:17;:26;:::i;:::-;52580:42;;52768:27;:16;:5;:14;:16::i;:27::-;52760:44;-1:-1:-1;52797:6:0;;-1:-1:-1;;;;;51883:926:0;;;;;;:::o;4775:160::-;4833:7;4859:5;;;4877:6;;;;4869:46;;;;;-1:-1:-1;;;4869:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;20407:97;20460:7;20481:18;:2;19694:19;20481:18;:6;:18;:::i;52932:847::-;53035:15;53052:14;53138;53154:13;53171:34;53188:9;53199:5;53171:16;:34::i;:::-;53137:68;;;;53319:8;:6;:8::i;:::-;-1:-1:-1;;;;;53319:21:0;;:23;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;53319:23:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;53319:23:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;53319:23:0;53305:59;;;-1:-1:-1;;;53305:59:0;;-1:-1:-1;;;;;53305:59:0;;;;;;;;;:48;;;;;;;:59;;;;;53319:23;;53305:59;;;;;;;:48;:59;;;5:2:-1;;;;30:1;27;20:12;5:2;53305:59:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;53305:59:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;53305:59:0;53296:112;;53393:1;;-1:-1:-1;53396:5:0;-1:-1:-1;53385:17:0;;-1:-1:-1;53385:17:0;53296:112;53473:14;53490:44;53517:9;53528:5;53490:26;:44::i;:::-;53473:61;;53647:13;53663:85;53741:6;53663:68;53679:12;:10;:12::i;:::-;:51;;;-1:-1:-1;;;53679:51:0;;-1:-1:-1;;;;;53679:51:0;;;;;;;;;;;;;;;;:33;;;;;;;:51;;;;;;;;;;;;;;;:33;:51;;;5:2:-1;;;;30:1;27;20:12;5:2;53679:51:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;53679:51:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;53679:51:0;53663:6;;:68;:15;:68;:::i;:::-;:77;:85;:77;:85;:::i;:::-;53647:101;53768:5;;-1:-1:-1;52932:847:0;;-1:-1:-1;;;;;;52932:847:0:o;55393:279::-;55487:31;55521:12;:10;:12::i;:::-;55487:46;;55538:13;55554:15;-1:-1:-1;;;;;55554:34:0;;55589:9;55554:45;;;;;;;;;;;;;-1:-1:-1;;;;;55554:45:0;-1:-1:-1;;;;;55554:45:0;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;55554:45:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;55554:45:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;55554:45:0;55604:63;;;-1:-1:-1;;;55604:63:0;;-1:-1:-1;;;;;55604:63:0;;;;;;;;;;;;;;;;;;;;;;55554:45;;-1:-1:-1;55604:38:0;;;;;;:63;;;;;-1:-1:-1;;55604:63:0;;;;;;;;-1:-1:-1;55604:38:0;:63;;;5:2:-1;;;;30:1;27;20:12;5:2;55604:63:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;55604:63:0;;;;55393:279;;;;:::o;51291:543::-;51427:15;51448:22;51476:21;51503:23;51532:22;51664:13;51680:15;-1:-1:-1;;;;;51680:51:0;;51737:9;51752:5;51680:82;;;;;;;;;;;;;-1:-1:-1;;;;;51680:82:0;-1:-1:-1;;;;;51680:82:0;;;;;;-1:-1:-1;;;;;51680:82:0;-1:-1:-1;;;;;51680:82:0;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51680:82:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;51680:82:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;51680:82:0;;-1:-1:-1;51782:8:0;:6;:8::i;:::-;-1:-1:-1;;;;;51782:15:0;;:17;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51782:17:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;51782:17:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;51782:17:0;51774:55;;;-1:-1:-1;;;51774:55:0;;-1:-1:-1;;;;;51774:55:0;;;;;;;;;;;;;;;:37;;;;;;;:55;;;;;;;;;;;;;;:37;:55;;;5:2:-1;;;;30:1;27;20:12;5:2;51774:55:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;51774:55:0;;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;51774:55:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;51774:55:0;-1:-1:-1;51774:55:0;;-1:-1:-1;51774:55:0;-1:-1:-1;51291:543:0;-1:-1:-1;;;;;51291:543:0:o;6013:411::-;6071:7;6292:6;6288:32;;-1:-1:-1;6313:1:0;6306:8;;6288:32;6338:5;;;6342:1;6338;:5;:1;6356:5;;;;;:10;6348:56;;;;-1:-1:-1;;;6348:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6856:123;6914:7;6935:39;6939:1;6942;6935:39;;;;;;;;;;;;;;;;;:3;:39::i;54807:498::-;54908:7;54924:31;54958:12;:10;:12::i;:::-;54991:69;;;-1:-1:-1;;;54991:69:0;;-1:-1:-1;;;;;54991:69:0;;;;;;;;;;;;;;;;54924:46;;-1:-1:-1;54975:13:0;;54991:38;;;;;;:69;;;;;;;;;;;;;;;:38;:69;;;5:2:-1;;;;30:1;27;20:12;5:2;54991:69:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;54991:69:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;54991:69:0;55081:45;;;-1:-1:-1;;;55081:45:0;;-1:-1:-1;;;;;55081:45:0;;;;;;;;;54991:69;;-1:-1:-1;55065:13:0;;55081:34;;;;;;:45;;;;;54991:69;;55081:45;;;;;;;;:34;:45;;;5:2:-1;;;;30:1;27;20:12;5:2;55081:45:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;55081:45:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;55081:45:0;;-1:-1:-1;55131:16:0;55150;55081:45;55160:5;55150:16;:9;:16;:::i;:::-;55131:35;;55171:15;55203:9;-1:-1:-1;;;;;55189:34:0;;55224:5;55189:41;;;;;;;;;;;;;-1:-1:-1;;;;;55189:41:0;-1:-1:-1;;;;;55189:41:0;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;55189:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;55189:41:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;55189:41:0;;-1:-1:-1;55235:13:0;55251:21;:8;55189:41;55251:21;:12;:21;:::i;:::-;55235:37;;55284:16;:5;:14;:16::i;:::-;55277:23;54807:498;-1:-1:-1;;;;;;;;;54807:498:0:o;7467:325::-;7566:7;7656:12;7649:5;7641:28;;;;-1:-1:-1;;;7641:28: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;7641:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7674:9;7690:1;7686;:5;;;;;;;7467:325;-1:-1:-1;;;;;7467:325:0:o;5180:127::-;5238:7;5259:43;5263:1;5266;5259:43;;;;;;;;;;;;;;;;;5707:7;5737:12;5729:6;;;;5721:29;;;;-1:-1:-1;;;5721:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27:10:-1;;8:100;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;5721:29:0;-1:-1:-1;;;5767:5:0;;;5608:184::o

Swarm Source

bzzr://667b5de3a803aaac8684108683c8810e13256a965db08b51f2f62d7cb8b8b153

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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