Contract 0xddAEcf4B02A3e45b96FC2d7339c997E072b0d034 19

 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x9da99daf424cac853aff90d39c87b394357692d622b16b25c4e23834971aee2fDeposit Vesting1850952872024-02-27 19:19:2357 mins ago0x2199201d8b525466c7115a66863daac1a2613827 IN  0xddaecf4b02a3e45b96fc2d7339c997e072b0d0340 ETH0.00013305 0.1
0xad8edab69cd80e11e575123132fab2afa237d3058554b746da71f7b69f86b564Unstake1850952092024-02-27 19:19:0257 mins ago0x2199201d8b525466c7115a66863daac1a2613827 IN  0xddaecf4b02a3e45b96fc2d7339c997e072b0d0340 ETH0.0001188 0.1
0x29169cfdf3d7bbc97c48f093eb50f4b7a1a368f3aac9ffcccded46254006a964Deposit Dividend1850878222024-02-27 18:46:481 hr 29 mins ago0xa3f8535481819e1210f5243a9aa2ed9899b6422a IN  0xddaecf4b02a3e45b96fc2d7339c997e072b0d0340 ETH0.00013414 0.1
0x1540d3d6144a37f72f4602e3497bf583002f5d0dc10614bc1fcd2a19092a9465Deposit Dividend1850876852024-02-27 18:46:131 hr 30 mins ago0xa3f8535481819e1210f5243a9aa2ed9899b6422a IN  0xddaecf4b02a3e45b96fc2d7339c997e072b0d0340 ETH0.00014087 0.1
0x42d6d33de65f597961a345bb12313d383c137f5b5b35c95a4978a979f9df5348Deposit Dividend1850873072024-02-27 18:44:351 hr 32 mins ago0x5f106a62067b2663b1286a9876afb80ad494b21e IN  0xddaecf4b02a3e45b96fc2d7339c997e072b0d0340 ETH0.00014087 0.1
0x936c686f826ecdcc6612c5ec0ca16de37e8071f13dc86ba2f9c2a1f94194d81cClaim Vesting1850858292024-02-27 18:38:001 hr 38 mins ago0xa6dd295e59a7f85a601066a5251f79c929f966ae IN  0xddaecf4b02a3e45b96fc2d7339c997e072b0d0340 ETH0.00016994 0.1
0x536df9ee5248157b866ae34801b2ca4c080f027db018b7495597834ea618a91bUnstake1850765402024-02-27 17:57:242 hrs 19 mins ago0x558e3872b3d73c2428bba889539ab0c56b5df79a IN  0xddaecf4b02a3e45b96fc2d7339c997e072b0d0340 ETH0.000182720.1
0xb1ecf879bba5d9d42872075ba7b6f5336dfd3a798ac1c8346075b46c77e94c20Claim Dividend1850763362024-02-27 17:56:342 hrs 20 mins ago0x558e3872b3d73c2428bba889539ab0c56b5df79a IN  0xddaecf4b02a3e45b96fc2d7339c997e072b0d0340 ETH0.000145780.1
0x9d8be2a453d5dee6aa7f8285936b523910b4cdc3146fb8b3782a340d6a7de83dDeposit Vesting1850754732024-02-27 17:52:512 hrs 23 mins ago0x558e3872b3d73c2428bba889539ab0c56b5df79a IN  0xddaecf4b02a3e45b96fc2d7339c997e072b0d0340 ETH0.000236990.1
0xfa48e16ced187744597a2d3147031577f66d920f1272bc0920463eaaf875bdeeDeposit Vesting1850653572024-02-27 17:09:393 hrs 7 mins ago0x3afe151e4b3bf56ff0d467ba13152fbb0f34cb28 IN  0xddaecf4b02a3e45b96fc2d7339c997e072b0d0340 ETH0.00017339 0.1
0xddff1555b60c58a8a4ecd512c2e2760030b0c34f7009c24aea49f456ac00b8c6Unstake1850651742024-02-27 17:08:503 hrs 7 mins ago0x3afe151e4b3bf56ff0d467ba13152fbb0f34cb28 IN  0xddaecf4b02a3e45b96fc2d7339c997e072b0d0340 ETH0.00016202 0.1
0x66abce6c1982ecf80f7dbf1dbfb1ea925f66ad8540947bc6afc8fbc2e9e4c6edDeposit Vesting1850551582024-02-27 16:25:493 hrs 50 mins ago0xb4a3c2debfc033ee3399ad6adf0b4fc74db92baa IN  0xddaecf4b02a3e45b96fc2d7339c997e072b0d0340 ETH0.000146320.1
0x5a8f8a17199adc909403b85187a3f309d59f44e4fc6f9ee6a0043b7040825f59Claim Vesting1850549812024-02-27 16:25:033 hrs 51 mins ago0x29e3ddf94d76c97fcd43d07fc8b15a03ad233a40 IN  0xddaecf4b02a3e45b96fc2d7339c997e072b0d0340 ETH0.00015386 0.1
0x1597254bf74112711f53c1c14d87ccc664f45cc1b047b3d96b807652a90018efDeposit Vesting1850549572024-02-27 16:24:563 hrs 51 mins ago0x29e3ddf94d76c97fcd43d07fc8b15a03ad233a40 IN  0xddaecf4b02a3e45b96fc2d7339c997e072b0d0340 ETH0.00014829 0.1
0x5b443a50a1368f65b66071db73f5ae84cc91a6ea00e048afe54454576c052d0eWithdraw Vesting1850548652024-02-27 16:24:333 hrs 52 mins ago0xb4a3c2debfc033ee3399ad6adf0b4fc74db92baa IN  0xddaecf4b02a3e45b96fc2d7339c997e072b0d0340 ETH0.000122370.1
0x3b536f8d14e73e486e50cd8c183f3c9e198294b6ffa49c2d1e92fccdc3333400Deposit Vesting1850510742024-02-27 16:08:394 hrs 8 mins ago0x7b005cf5cb7a3222fda9df1c344848ddf45a64b0 IN  0xddaecf4b02a3e45b96fc2d7339c997e072b0d0340 ETH0.00011096 0.1
0x68a9130ed203a878db51b1aa69d90737d90d74f04c1da5b913e932977455a325Claim Dividend1850464622024-02-27 15:49:134 hrs 27 mins ago0x4996e80b4d334aecc2427b2dd9ebcaf44985ceaa IN  0xddaecf4b02a3e45b96fc2d7339c997e072b0d0340 ETH0.00005999 0.1
0x7b6e020adab71c07cd4e97735a64fe776402c369f3c491d3ca5786156306ae70Claim Dividend1850463362024-02-27 15:48:434 hrs 28 mins ago0x4996e80b4d334aecc2427b2dd9ebcaf44985ceaa IN  0xddaecf4b02a3e45b96fc2d7339c997e072b0d0340 ETH0.00007921 0.1
0x5c90549bed39373e0ec859025b59db7d8f82e2a9cfbd1359126b5ded1723dc9dWithdraw Vesting1850449092024-02-27 15:42:384 hrs 34 mins ago0x69bcf4901079da6d14b49ad071cf7dbf0f767da0 IN  0xddaecf4b02a3e45b96fc2d7339c997e072b0d0340 ETH0.00011425 0.1
0x611f451b7f325938bd076c49a3bc87aff34da88bc0494af492683d8a323b6099Withdraw Vesting1850448802024-02-27 15:42:334 hrs 34 mins ago0x69bcf4901079da6d14b49ad071cf7dbf0f767da0 IN  0xddaecf4b02a3e45b96fc2d7339c997e072b0d0340 ETH0.00014635 0.1
0xdc54d6284540310ca294fb9dff7f5a4d5aaf7dc1bb9ccc846512e0ad2040532dUnstake1850343582024-02-27 14:57:555 hrs 18 mins ago0x48e2a511e5956e5b3f321c43d8ddec68ef9ae94e IN  0xddaecf4b02a3e45b96fc2d7339c997e072b0d0340 ETH0.000135380.1
0x9a32660bdce9c7c021d598283fdc6f98fb6038c0b375054ed01297f4bcde2d33Unstake1850337822024-02-27 14:55:315 hrs 21 mins ago0x53810072454678b3c68359521352a8b2ad9a4259 IN  0xddaecf4b02a3e45b96fc2d7339c997e072b0d0340 ETH0.0001459 0.1
0x7ce5f03de877dad0af5c2e54ca990562ee4dbfe58227aae64856e486e99090f5Deposit Vesting1850289212024-02-27 14:34:585 hrs 41 mins ago0xe015ea3b1fa4645fcaa2d3e7033e72b518390bde IN  0xddaecf4b02a3e45b96fc2d7339c997e072b0d0340 ETH0.000153 0.1
0x0107a8a85ea14511aad5361c68ae4d465d147e4e025f649b74c0a56d3e7ccbfeDeposit Dividend1850203642024-02-27 13:59:016 hrs 17 mins ago0x4f6dc6432e532e8672b2225124eb04d4523a8b7d IN  0xddaecf4b02a3e45b96fc2d7339c997e072b0d0340 ETH0.0001257 0.1
0xcb8a72fb142bc85bc4138ce193d3aa46b67abee20e153359ccbd04030051e587Claim Vesting1849991982024-02-27 12:30:277 hrs 46 mins ago0x207495e53aa552c10e44c7cc9dcaceb83b2eb688 IN  0xddaecf4b02a3e45b96fc2d7339c997e072b0d0340 ETH0.00013092 0.1
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
WINRStaking

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 12 : WINRStaking.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import "./WINRVesting.sol";

contract WINRStaking is WINRVesting {
	/*==================================================== State Variables ========================================================*/
	mapping(address => StakeDividend) public dividendWINRStakes;
	mapping(address => StakeDividend) public dividendVestedWINRStakes;

	/*==================================================== Constructor ===========================================================*/
	constructor(
		address _vaultRegistry,
		address _timelock
	) WINRVesting(_vaultRegistry, _timelock) {}

	/*===================================================== FUNCTIONS ============================================================*/
	/*=================================================== View Functions =========================================================*/

	/**
	 *
	 * @dev Retrieves the staked amount of dividend WINR tokens for a specified account and stake type.
	 * @param _account The address of the account to retrieve the staked amount for.
	 * @param _isVested A boolean flag indicating whether to retrieve the vested WINR or WINR dividend stake.
	 * @return _amount The staked amount of dividend WINR/vWINR tokens for the specified account and stake type.
	 * @dev The function retrieves the staked amount of dividend WINR/vWINR tokens for the specified account and stake type from the dividendWINRStakes or dividenVestedWINRdStakes mapping,
	 *      depending on the value of the isVested parameter.
	 */
	function dividendStakedAmount(
		address _account,
		bool _isVested
	) external view returns (uint256) {
		return
			_isVested
				? dividendVestedWINRStakes[_account].amount
				: dividendWINRStakes[_account].amount;
	}

	/**
	 *
	 * @dev Retrieves the dividend stake for a specified account and stake type.
	 * @param _account The address of the account to retrieve the dividend stake for.
	 * @param _isVested A boolean flag indicating whether to retrieve the vested or non-vested dividend stake.
	 * @return stake A Stake struct representing the dividend stake for the specified account and stake type.
	 * @dev The function retrieves the dividend stake for the specified account and stake type from the dividendWINRStakes or dividenVestedWINRdStakes mapping, depending on the value of the isVested parameter.
	 */
	function getDividendStake(
		address _account,
		bool _isVested
	) external view returns (StakeDividend memory) {
		return
			_isVested
				? dividendVestedWINRStakes[_account]
				: dividendWINRStakes[_account];
	}

	/**
	 *
	 * @param _account The address of the account to retrieve the pending rewards data.
	 */
	function pendingDividendRewards(address _account) external view returns (uint256 pending_) {
		// Calculate the pending reward based on the dividend vested WINR stake of the given account
		pending_ += _pendingByDividendStake(dividendVestedWINRStakes[_account]);
		// Calculate the pending reward based on the dividend WINR stake of the given account
		pending_ += _pendingByDividendStake(dividendWINRStakes[_account]);
	}

	/*================================================= External Functions =======================================================*/
	/**
	 *
	 * @dev Fallback function that handles incoming Ether transfers to the contract.
	 * @dev The function emits a Donation event with the sender's address and the amount of Ether transferred.
	 * @dev The function can receive Ether and can be called by anyone, but does not modify the state of the contract.
	 */
	fallback() external payable {
		emit Donation(msg.sender, msg.value);
	}

	/**
	 *
	 * @dev Receive function that handles incoming Ether transfers to the contract.
	 * @dev The function emits a Donation event with the sender's address and the amount of Ether transferred.
	 * @dev The function can receive Ether and can be called by anyone, but does not modify the state of the contract.
	 */
	receive() external payable {
		emit Donation(msg.sender, msg.value);
	}

	/**
	 *
	 * @dev Distributes a share of profits to all stakers based on their stake weight.
	 * @param _amount The amount of profits to distribute among stakers.
	 * @notice The function can only be called by an address with the PROTOCOL_ROLE.
	 * @notice The total weight of all staked tokens must be greater than zero for profits to be distributed.
	 * @dev If the total weight of all staked tokens is greater than zero,
	 *      the function adds the specified amount of profits to the total profit pool
	 *      and updates the accumulated profit per weight value accordingly.
	 * @dev The function emits a Share event to notify external systems about the distribution of profits.
	 */
	function share(uint256 _amount) external override isAmountNonZero(_amount) onlyProtocol {
		if (totalWeight > 0) {
			totalProfit += _amount;
			totalEarned += _amount;
			accumProfitPerWeight += (_amount * PRECISION) / totalWeight;

			emit Share(_amount, totalWeight, totalStakedVestedWINR, totalStakedWINR);
		}
	}

	/**
	 *
	 *  @dev Function to claim dividends for the caller.
	 *  @notice The function can only be called when the contract is not paused and is non-reentrant.
	 *  @notice The function calls the internal function '_claimDividend' passing the caller's address and 'isVested' boolean as parameters.
	 */
	function claimDividend() external whenNotPaused nonReentrant {
		_claimDividendBatch(msg.sender);
	}

	/**
	 * @notice Pauses the contract. Only the governance address can call this function.
	 * @dev While the contract is paused, some functions may be disabled to prevent unexpected behavior.
	 */
	function pause() public onlyTeam {
		_pause();
	}

	/**
	 * @notice Unpauses the contract. Only the governance address can call this function.
	 * @dev Once the contract is unpaused, all functions should be enabled again.
	 */
	function unpause() public onlyTeam {
		_unpause();
	}

	/**
	 * @notice Allows the governance to withdraw a certain amount of donations and transfer them to a specified address
	 * @param to The address to transfer the donations to
	 * @param amount The amount of donations to withdraw
	 */
	function withdrawDonations(address payable to, uint256 amount) external onlyGovernance {
		require(address(this).balance >= amount, "Insufficient balance");
		(bool sent, ) = to.call{value: amount}("");
		require(sent, "Withdraw failed");
	}

	/**
	 * @dev Updates the vesting period configuration.
	 * @param duration Total vesting duration in seconds.
	 * @param minDuration Minimum vesting duration in seconds.
	 * @param claimDuration Duration in seconds during which rewards can be claimed.
	 * @param minPercent Minimum percentage of the total stake that must be vested.
	 */
	function updatePeriod(
		uint256 duration,
		uint256 minDuration,
		uint256 claimDuration,
		uint256 minPercent
	) external onlyGovernance {
		require(
			duration >= minDuration,
			"Duration must be greater than or equal to minimum duration"
		);
		require(
			claimDuration <= duration,
			"Claim duration must be less than or equal to duration"
		);

		period.duration = duration;
		period.minDuration = minDuration;
		period.claimDuration = claimDuration;
		period.minPercent = minPercent;
	}

	/**
	 *
	 * @dev Internal function to deposit WINR/vWINR as dividends.
	 * @param _amount The amount of WINR/vWINR to be deposited.
	 * @param _isVested Boolean flag indicating if tokens are vWINR.
	 * @dev This function performs the following steps:
	 *     Get the address of the stake owner.
	 *     Determine the stake details based on the boolean flag isVested.
	 *     Take the tokens from the stake owner and update the stake amount.
	 *     If the stake amount is greater than 0, claim dividends for the stake owner.
	 *     Calculate the stake weight based on the updated stake amount and isVested flag.
	 *     Update the stake with the new stake amount, start time, weight and profit debt.
	 *     Emit a Deposit event with the details of the deposited tokens.
	 */
	function depositDividend(
		uint256 _amount,
		bool _isVested
	) external isAmountNonZero(_amount) nonReentrant whenNotPaused {
		// Get the address of the stake owner.
		address sender_ = msg.sender;
		// Determine the stake details based on the boolean flag isVested.
		StakeDividend storage stake_;

		if (_isVested) {
			tokenManager.takeVestedWINR(sender_, _amount);
			stake_ = dividendVestedWINRStakes[sender_];
			totalStakedVestedWINR += _amount;
		} else {
			tokenManager.takeWINR(sender_, _amount);
			stake_ = dividendWINRStakes[sender_];
			totalStakedWINR += _amount;
		}

		// If the stake amount is greater than 0, claim dividends for the stake owner.
		if (stake_.amount > 0) {
			_claimDividend(sender_, _isVested);
		}

		// Calculate the stake weight
		uint256 weight_ = _calculateWeight(stake_.amount + _amount, _isVested, false);
		// increase the total staked weight
		totalWeight += (weight_ - stake_.weight);
		// Update the stake with the new stake amount, start time, weight and profit debt.
		stake_.amount += _amount;
		stake_.depositTime = uint128(block.timestamp);
		stake_.weight = weight_;
		stake_.profitDebt = _calcDebt(weight_);

		// Emit a DepositDividend event with the details of the deposited tokens.
		emit DepositDividend(sender_, stake_.amount, stake_.profitDebt, _isVested);
	}

	/**
	 *
	 * @dev Internal function to unstake tokens.
	 * @param _amount The amount of tokens to be unstaked.
	 * @param _isVested Boolean flag indicating if stake is Vested WINR.
	 * @notice This function also claims rewards.
	 * @dev This function performs the following steps:
	 *    Check that the staker has sufficient stake amount.
	 *    Claim dividends for the staker.
	 *    Compute the weight of the unstaked tokens and update the total staked amount and weight.
	 *    Compute the debt for the stake after unstaking tokens.
	 *    Burn the necessary amount of tokens and send the remaining unstaked tokens to the staker.
	 *    Emit an Unstake event with the details of the unstaked tokens.
	 */
	function unstake(uint256 _amount, bool _isVested) external nonReentrant whenNotPaused {
		address sender_ = msg.sender;
		StakeDividend storage stake_ = _isVested
			? dividendVestedWINRStakes[sender_]
			: dividendWINRStakes[sender_];
		require(stake_.amount >= _amount, "Insufficient stake amount");
		ITokenManager tokenManager_ = tokenManager;

		// Compute the amount of tokens to be burned and sent to the staker.
		uint256 burnAmount_ = _computeBurnAmount(_amount);
		uint256 sendAmount_ = _amount - burnAmount_;
		// Compute the weight of the unstaked tokens and update the total staked amount and weight.
		uint256 unstakedWeight_;

		// Claim dividends for the staker.
		_claimDividend(sender_, _isVested);

		// Burn the necessary amount of tokens and send the remaining unstaked tokens to the staker.
		if (_isVested) {
			tokenManager_.burnVestedWINR(burnAmount_);
			tokenManager_.sendVestedWINR(sender_, sendAmount_);
			unstakedWeight_ = _amount * weightMultipliers.vWinr;
			totalStakedVestedWINR -= _amount;
		} else {
			tokenManager_.burnWINR(burnAmount_);
			tokenManager_.sendWINR(sender_, sendAmount_);
			unstakedWeight_ = _amount * weightMultipliers.winr;
			totalStakedWINR -= _amount;
		}

		totalWeight -= unstakedWeight_;

		// Update the stake details after unstaking tokens.
		stake_.amount -= _amount;
		stake_.weight -= unstakedWeight_;
		stake_.profitDebt = _calcDebt(stake_.weight);

		// Emit an Unstake event with the details of the unstaked tokens.
		emit Unstake(sender_, block.timestamp, sendAmount_, burnAmount_, _isVested);
	}

	/*================================================= Internal Functions =======================================================*/
	/**
	 *
	 * @dev Internal function to claim dividends for a stake.
	 * @param _account The address of the stake owner.
	 * @param _isVested Boolean flag indicating if stake is Vested WINR.
	 * @return reward_ The amount of dividends claimed.
	 * @dev This function performs the following steps:
	 *     Determine the stake details based on the boolean flag isVested.
	 *     Calculate the pending rewards for the stake.
	 *     Send the rewards to the stake owner.
	 *     Update the profit debt for the stake.
	 *     Update the total profit and total claimed for the stake owner.
	 *     Emit a Claim event with the details of the claimed rewards.
	 */
	function _claimDividend(
		address _account,
		bool _isVested
	) internal returns (uint256 reward_) {
		// Determine the stake details based on the boolean flag isVested.
		StakeDividend storage stake_ = _isVested
			? dividendVestedWINRStakes[_account]
			: dividendWINRStakes[_account];

		// Calculate the pending rewards for the stake.
		reward_ = _pendingByDividendStake(stake_);

		if (reward_ == 0) {
			return 0;
		}

		// Send the rewards to the stake owner.
		tokenManager.sendWLP(_account, reward_);

		// Update the profit debt for the stake.
		stake_.profitDebt = _calcDebt(stake_.weight);

		// Update the total profit and total claimed for the stake owner.
		// totalProfit -= _reward;
		totalClaimed[_account] += reward_;

		// Emit a Claim event with the details of the claimed rewards.
		emit ClaimDividend(_account, reward_, _isVested);
	}

	/**
	 *
	 * @dev Internal function to claim dividends for all stake.
	 * @param _account The address of the stake owner.
	 * @return reward_ The amount of dividends claimed.
	 */
	function _claimDividendBatch(address _account) internal returns (uint256 reward_) {
		// Determine the stake details based on the boolean flag isVested.
		StakeDividend storage stakeVWINR_ = dividendVestedWINRStakes[_account];
		StakeDividend storage stakeWINR_ = dividendWINRStakes[_account];

		// Calculate the pending rewards for the stake.
		reward_ = _pendingByDividendStake(stakeVWINR_);
		reward_ += _pendingByDividendStake(stakeWINR_);

		if (reward_ == 0) {
			return 0;
		}

		// Send the rewards to the stake owner.
		tokenManager.sendWLP(_account, reward_);

		// Update the profit debt for the stake.
		stakeVWINR_.profitDebt = _calcDebt(stakeVWINR_.weight);
		stakeWINR_.profitDebt = _calcDebt(stakeWINR_.weight);

		// Update the total profit and total claimed for the stake owner.
		totalClaimed[_account] += reward_;

		// Emit a Claim event with the details of the claimed rewards.
		emit ClaimDividendBatch(_account, reward_);
	}

	/**
	 * @notice Computes the pending WLP amount of the stake.
	 * @param _stake The stake for which to compute the pending amount.
	 * @return holderProfit_ The pending WLP amount.
	 */
	function _pendingByDividendStake(
		StakeDividend memory _stake
	) internal view returns (uint256 holderProfit_) {
		// Compute the holder's profit as the product of their stake's weight and the accumulated profit per weight.
		holderProfit_ = ((_stake.weight * accumProfitPerWeight) / PRECISION);
		// If the holder's profit is less than their profit debt, return zero.
		if (holderProfit_ < _stake.profitDebt) {
			return 0;
		} else {
			// Otherwise, subtract their profit debt from their total profit and return the result.
			holderProfit_ -= _stake.profitDebt;
		}
	}
}

File 2 of 12 : WINRVesting.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import "solmate/src/utils/ReentrancyGuard.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "../../core/AccessControlBase.sol";
import "../../interfaces/core/ITokenManager.sol";
import "../../interfaces/tokens/IWINR.sol";
import "../../interfaces/stakings/IWINRStaking.sol";

abstract contract WINRVesting is IWINRStaking, Pausable, ReentrancyGuard, AccessControlBase {
	/*====================================================== Modifiers ===========================================================*/
	/**
	 * @notice Throws if the amount is not greater than zero
	 */
	modifier isAmountNonZero(uint256 amount) {
		require(amount > 0, "amount must be greater than zero");
		_;
	}

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

	// 18 decimal precision
	uint256 internal constant PRECISION = 1e18;
	//The total profit earned by all staked tokens in the contract
	uint256 public totalProfit;
	//The total weight of all stakes in the contract
	uint256 public totalWeight;
	//The total amount of WINR tokens staked in the contract
	uint256 public totalStakedWINR;
	//The total amount of vWINR tokens staked in the contract
	uint256 public totalStakedVestedWINR;
	//The accumulated profit per weight of all stakes in the contract. It is used in the calculation of rewards earned by each stakeholder
	uint256 public accumProfitPerWeight;
	//The percentage of staked tokens that will be burned when a stake is withdrawn
	uint256 public unstakeBurnPercentage;
	//The total profit history earned by all staked tokens in the contract
	uint256 public totalEarned;
	//Interface of Token Manager contract
	ITokenManager public tokenManager;
	//This mapping stores an array of StakeVesting structures for each address that has staked tokens in the contract
	mapping(address => StakeVesting[]) public stakes;
	//This mapping stores an array of indexes into the stakes array for each address that has active vesting stakes in the contract
	mapping(address => uint256[]) public activeVestingIndexes;
	//This mapping stores the total amount of tokens claimed by each address that has staked tokens in the contract
	mapping(address => uint256) public totalClaimed;
	//Initializes default vesting period
	Period public period = Period(180 days, 15 days, 165, 5e17);
	//Initializes default reward multipliers
	WeightMultipliers public weightMultipliers = WeightMultipliers(1, 2, 1);

	/*==================================================== Constructor ===========================================================*/
	constructor(
		address _vaultRegistry,
		address _timelock
	) AccessControlBase(_vaultRegistry, _timelock) {
		unstakeBurnPercentage = 5e15; // 0.5% default
	}

	/*===================================================== FUNCTIONS ============================================================*/
	/*=================================================== View Functions =========================================================*/
	/**
	 *
	 * @dev Calculates the pending reward for a given staker.
	 * @param account The address of the staker for whom to calculate the pending reward.
	 * @return pending The amount of pending WLP tokens that the staker is eligible to receive.
	 * @dev The function iterates over all active stakes for the given staker and calculates the pending rewards for each stake using the _pendingWLPOfStake() internal function.
	 * @dev The function is view-only and does not modify the state of the contract.
	 */
	function pendingVestingRewards(address account) external view returns (uint256 pending) {
		uint256[] memory activeIndexes = getActiveIndexes(account);

		for (uint256 i = 0; i < activeIndexes.length; i++) {
			StakeVesting memory stake = stakes[account][activeIndexes[i]];
			pending += _pendingWLPOfStake(stake);
		}
	}

	/**
	 *
	 * @dev Calculates the pending reward for a given staker with given index.
	 * @param account The address of the staker for whom to calculate the pending reward.
	 * @return pending The amount of pending WLP tokens that the staker is eligible to receive.
	 * @dev The function calculates the pending rewards for the stake using the _pendingWLPOfStake() internal function.
	 * @dev The function is view-only and does not modify the state of the contract.
	 */
	function pendingVestingByIndex(
		address account,
		uint256 index
	) external view returns (uint256 pending) {
		// Get the stake from the stakes mapping
		StakeVesting memory stake = stakes[account][index];
		if(stake.withdrawn || stake.cancelled) return 0;
		// Calculate the pending reward for the stake
		pending = _pendingWLPOfStake(stake);
	}

	/**
	 *
	 * @param _account Address of staker
	 * @param _index index to calculate the withdrawable amount
	 * @return _withdrawable  withdrawable amount of WINR/vWINR
	 */
	function withdrawableTokens(
		address _account,
		uint256 _index
	) external view returns (uint256 _withdrawable) {
		// Get the stake from the stakes mapping
		StakeVesting memory _stake = stakes[_account][_index];
		// Calculate the withdrawable amount for the stake
		_withdrawable = _withdrawableByVesting(_stake);

		// Check if the vesting period has passed
		if (_stake.startTime + _stake.vestingDuration > block.timestamp) {
			_withdrawable = 0;
		}
	}

	/**
	 * @notice This function returns an array of indexes representing the active vesting stakes indexes for a given staker.
	 * @param staker The address of the staker
	 */
	function getActiveIndexes(address staker) public view returns (uint[] memory indexes) {
		indexes = activeVestingIndexes[staker];
	}

	/**
	 *
	 * @param _account Address of the staker
	 * @param _indexes Indexes of the vesting stakes to calculate the total staked amount
	 * @return _totalStaked The total amount of staked tokens across the specified vesting stakes
	 */
	function vestingStakedAmount(
		address _account,
		uint256[] calldata _indexes
	) external view returns (uint256 _totalStaked) {
		for (uint256 i = 0; i < _indexes.length; i++) {
			StakeVesting memory _stake = stakes[_account][_indexes[i]];
			_totalStaked += _stake.amount;
		}
	}

	/**
	 * @return _totalStakedVWINR The total amount of vWINR tokens staked in the contract
	 * @return _totalStakedWINR The total amount of WINR tokens staked in the contract
	 * @return _totalEarned The total profit earned
	 */
	function globalData()
		external
		view
		returns (uint256 _totalStakedVWINR, uint256 _totalStakedWINR, uint256 _totalEarned)
	{
		_totalStakedVWINR = totalStakedVestedWINR;
		_totalStakedWINR = totalStakedWINR;
		_totalEarned = totalEarned;
	}

	/**
	 *
	 * @param _account Address of staker
	 * @param _index Index of stake
	 * @return _stake Data of the stake
	 */
	function getVestingStake(
		address _account,
		uint256 _index
	) public view returns (StakeVesting memory _stake) {
		_stake = stakes[_account][_index];
	}

	/**
	 *
	 * @param _account Address of staker
	 * @return _length total stake count of the _account
	 */
	function getVestingStakeLength(address _account) external view returns (uint256 _length) {
		_length = stakes[_account].length;
	}

	function _calcDebt(uint256 _weight) internal view returns (uint256 debt) {
		debt = (_weight * accumProfitPerWeight) / PRECISION;
	}

	/**
	 *
	 * @dev Computes the weight of a specified amount of tokens based on its type and vesting status.
	 * @param amount The amount of tokens to compute the weight for.
	 * @param vested A boolean flag indicating whether the tokens are vested or not.
	 * @param vesting A boolean flag indicating whether the tokens are vesting or not, applicable only if the tokens are vested.
	 * @return The weight of the specified amount of tokens.
	 * @dev The function computes the weight of the specified amount of tokens based on its type and vesting status, using the weightMultipliers mapping.
	 * @dev The function does not modify the state of the contract and can only be called internally.
	 */
	function _calculateWeight(
		uint256 amount,
		bool vested,
		bool vesting
	) internal view returns (uint256) {
		return
			!vested ? amount * weightMultipliers.winr : vesting
				? amount * weightMultipliers.vWinrVesting
				: amount * weightMultipliers.vWinr;
	}

	/**
	 * @notice Computes the pending WLP amount of the stake.
	 * @param stake The stake for which to compute the pending amount.
	 * @return holderProfit The pending WLP amount.
	 */
	function _pendingWLPOfStake(StakeVesting memory stake) internal view returns (uint256) {
	// Compute the holder's profit as the product of their stake's weight and the accumulated profit per weight.
		uint256 holderProfit = ((stake.weight * accumProfitPerWeight) / PRECISION);
		// If the holder's profit is less than their profit debt, return zero.
		return holderProfit < stake.profitDebt ? 0 : holderProfit - stake.profitDebt;
	}

	/**
	 * @notice Calculates the amount of WINR/vWINR that should be burned upon unstaking.
	 * @param amount The amount of WINR/vWINR being unstaked.
	 * @return _burnAmount The amount of WINR/vWINR to be burned.
	 */
	function _computeBurnAmount(uint256 amount) internal view returns (uint256 _burnAmount) {
		// Calculate the burn amount as the product of the unstake burn percentage and the amount being unstaked.
		_burnAmount = (amount * unstakeBurnPercentage) / PRECISION;
	}

	/**
	 * @notice Computes the withdrawable amount of WINR for the stake.
	 * @param stake The stake for which to compute the withdrawable amount.
	 * @return withdrawable_ The withdrawable amount of WINR.
	 */
	function _withdrawableByVesting(
		StakeVesting memory stake
	) internal view returns (uint256 withdrawable_) {
		// Compute the total amount of time that the stake has been staked, in days.
		uint256 totalStakedDuration_ = (block.timestamp - stake.startTime) / 1 days;
		// Compute the minimum number of days required for staking in order to be eligible for a reward.
		uint256 _minDays = period.minDuration / 1 days;

		// If the stake duration is less than the minimum number of days, the holder cannot withdraw any tokens.
		if (totalStakedDuration_ < _minDays) {
			return 0;
		}

		// Otherwise, calculate the holder's profit as follows:
		if (block.timestamp > stake.startTime + stake.vestingDuration) {
			// If the vesting period has expired, then the holder can withdraw their full stake amount.
			totalStakedDuration_ = stake.vestingDuration / 1 days;
		}

		// Calculate the profit for the holder as the sum of the tokens earned on the first day and the additional tokens earned over time.
		withdrawable_ =
			stake.accTokenFirstDay +
			((stake.amount - stake.accTokenFirstDay) *
				(totalStakedDuration_ - _minDays)) /
			period.claimDuration;
	}

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

	/**
	 * @dev This function cancels vesting stakes without penalty and reward.
	 * It sends the staked amount to the staker.
	 * @param _index index to cancel vesting for
	 * @notice Throws an error if the stake has already been withdrawn
	 * @notice Emits a Cancel event upon successful execution
	 */
	function cancel(uint256 _index) external {
		// Get the address of the caller
		address sender_ = msg.sender;
		// Declare local variables for stake and bool values
		StakeVesting memory stake;
		

		// Retrieve the stake and bool values for the given index and staker
		(stake) = getVestingStake(sender_, _index);

		// Check if the stake has already been withdrawn
		require(!stake.withdrawn, "stake has withdrawn");
		// Check if the stake has already been cancelled
		require(!stake.cancelled, "stake has cancelled");

		// Remove the index from the staker's active stakes list
		_removeActiveIndex(sender_, _index);

		uint256 amount_ = stake.amount;


		// Calculate the amount of tokens to burn and the amount of tokens to send to the staker
		uint256 burnAmount_ = _computeBurnAmount(amount_);
		uint256 sendAmount_ = amount_ - burnAmount_;
		totalStakedVestedWINR -= amount_;
		totalWeight -= stake.weight;
		// claim rewards
		uint256 reward_ = _pendingWLPOfStake(stake);

		// share rewards with the pool
		if(reward_ > 0) {
			// Update the accumulated profit per weight
			accumProfitPerWeight += (reward_ * PRECISION) / totalWeight;
			// Update the holder's profit debt
			stakes[sender_][_index].profitDebt += reward_;
		}
		// Mark the stake as cancelled in the mapping
		stakes[sender_][_index].cancelled = true;
		stakes[sender_][_index].amount = 0;

		// Send the staked tokens to the staker
		tokenManager.sendVestedWINR(sender_, sendAmount_);

		// Burn the remaining vesting tokens
		tokenManager.burnVestedWINR(burnAmount_);

		// Emit a Cancel event to notify listeners of the cancellation
		emit Cancel(sender_, block.timestamp, _index, burnAmount_, sendAmount_);
	}


	/**
	 * @dev Set the percentage of tokens to burn upon unstaking. Only callable by the governance address.
	 * @param _unstakeBurnPercentage The percentage of tokens to burn upon unstaking
	 * @notice Emits an UnstakeBurnPercentageUpdate event upon successful execution
	 */
	function setUnstakeBurnPercentage(uint256 _unstakeBurnPercentage) external onlyGovernance {
		// Set the unstake burn percentage to the provided value
		unstakeBurnPercentage = _unstakeBurnPercentage;

		// Emit an event to notify listeners of the update
		emit UnstakeBurnPercentageUpdate(_unstakeBurnPercentage);
	}

	/**
	 * @dev Set the address of the token manager contract. Only callable by the governance address.
	 * @param _tokenManager The address of the token manager contract
	 */
	function setTokenManager(ITokenManager _tokenManager) external onlyGovernance {
		require(
			address(_tokenManager) != address(0),
			"token manager address can not be zero"
		);
		// Set the token manager to the provided address
		tokenManager = _tokenManager;
	}

	/**
	 * @dev Deposit vWINR tokens into the contract and create a vesting stake with the specified parameters
	 * @param amount The amount of vWINR tokens to deposit
	 * @param vestingDuration The duration of the vesting period in seconds
	 */
	function depositVesting(
		uint256 amount,
		uint256 vestingDuration
	) external isAmountNonZero(amount) nonReentrant whenNotPaused {
		uint256 vestingDurationInSeconds = vestingDuration * 1 days;
		require(
			vestingDurationInSeconds >= period.minDuration &&
				vestingDuration <= period.duration,
			"duration must be in period"
		);
		// Get the address of the caller
		address sender = msg.sender;
		uint256 weight = _calculateWeight(amount, true, true);
		// Calculate the profit debt for the stake based on its weight
		uint256 profitDebt = _calcDebt(weight);
		// Get the current timestamp as the start time for the stake
		uint256 startTime = block.timestamp;
		// Calculate the accumulated token value for the first day of the claim period
		uint256 accTokenFirstDay = (amount * period.minPercent) / PRECISION;
		// Calculate the daily accumulation rate for the claim period
		uint256 accTokenPerDay = (amount - accTokenFirstDay) / period.claimDuration;

		// Transfer the vWINR tokens from the sender to the token manager contract
		tokenManager.takeVestedWINR(sender, amount);

		totalWeight += weight;
		totalStakedVestedWINR += amount;

		// Create a new stake with the specified parameters and add it to the list of stakes for the sender
		stakes[sender].push(
			StakeVesting(
				amount,
				weight,
				vestingDurationInSeconds,
				profitDebt,
				startTime,
				accTokenFirstDay,
				accTokenPerDay,
				false,
				false
			)
		);

		// Get the index of the newly added stake and add it to the list of active stakes for the sender
		uint256 _index = stakes[msg.sender].length - 1;
		_addActiveIndex(msg.sender, _index);

		// Emit a Deposit event to notify listeners of the new stake
		emit DepositVesting(
			sender,
			_index,
			startTime,
			vestingDurationInSeconds,
			amount,
			profitDebt,
			true,
			true
		);
	}

	/**
	 *
	 *  @dev Function to claim rewards for a specified array of indexes.
	 *  @param indexes The array of indexes to claim rewards for.
	 *  @notice The function can only be called when the contract is not paused and is non-reentrant.
	 *  @notice The function throws an error if the array of indexes is empty.
	 */
	function claimVesting(uint256[] calldata indexes) external whenNotPaused nonReentrant {
		require(indexes.length > 0, "empty indexes");
		_claim(indexes, true);
	}

	/**
	 * @dev Withdraws staked tokens and claims rewards
	 * @param _index Index to withdraw
	 */
	function withdrawVesting(uint256 _index) external whenNotPaused nonReentrant {
		address sender_ = msg.sender;
		// Initialize an array of size 4 to store the amounts
		StakeVesting storage stake_ = stakes[sender_][_index];

		// Check that the withdrawal period for this stake has passed
		require(
			block.timestamp >= stake_.startTime + stake_.vestingDuration,
			"You can't withdraw the stake yet"
		);
		// Check that this stake has not already been withdrawn
		require(!stake_.withdrawn, "already withdrawn");
		// Check that this stake has not been cancelled
		require(!stake_.cancelled, "stake cancelled");

		// Redeemable WINR amount by stake
		uint256 redeemable_ = _withdrawableByVesting(stake_);
		// Redeemable WLP amount by stake
		uint256 reward_ = _pendingWLPOfStake(stake_);
		
		// Interact with external contracts to complete the withdrawal process
		if (redeemable_ > 0) {
			// Mint reward tokens if necessary
			tokenManager.mintOrTransferByPool(sender_, redeemable_);
		}

		uint256 amountToBurn = stake_.amount - redeemable_;

		// Mint WINR tokens to decrease MAX_SUPPLY
		if (amountToBurn > 0) {
			// this code piece is used to decrease burn amount from WINR total supply
			tokenManager.mintWINR(address(tokenManager), amountToBurn);
			tokenManager.burnWINR(amountToBurn);
		}

		// Burn vested WINR tokens
		tokenManager.burnVestedWINR(stake_.amount);

		// Interactions
		if (reward_ > 0) {
			tokenManager.sendWLP(sender_, reward_);

			stakes[sender_][_index].profitDebt += reward_;
			totalProfit -= reward_;
			totalClaimed[sender_] += reward_;

			emit ClaimVesting(sender_, reward_, _index);
		}

		// Calculate the total amounts to be withdrawn
		// Mark this stake as withdrawn and remove its index from the active list
		stake_.withdrawn = true;
		_removeActiveIndex(sender_, _index);

		// Update the total weight and total staked amount
		totalWeight -= stake_.weight;
		totalStakedVestedWINR -= stake_.amount;

		// Emit an event to log the withdrawal
		emit Withdraw(
			sender_,
			block.timestamp,
			_index,
			stake_.weight,
			stake_.weight,
			stake_.amount
		);
	}

	/**
	 * @dev Withdraws staked tokens and claims rewards
	 * @param indexes Indexes to withdraw
	 */
	function withdrawVestingBatch(
		uint256[] calldata indexes
	) external whenNotPaused nonReentrant {
		address sender = msg.sender;
		// Initialize an array of size 4 to store the amounts
		uint256[4] memory _amounts;

		// Check effects for each stake to be withdrawn
		for (uint256 i = 0; i < indexes.length; i++) {
			// Get the stake and boolean values for this index
			uint256 index = indexes[i];
			StakeVesting storage stake = stakes[sender][index];

			// Check that the withdrawal period for this stake has passed
			require(
				block.timestamp >= stake.startTime + stake.vestingDuration,
				"You can't withdraw the stake yet"
			);

			// Check that this stake has not already been withdrawn
			require(!stake.withdrawn, "already withdrawn");

			// Check that this stake has not been cancelled
			require(!stake.cancelled, "stake cancelled");

			// Calculate the total amounts to be withdrawn
			_amounts[0] += stake.weight;
			_amounts[1] += _withdrawableByVesting(stake);
			_amounts[2] += _pendingWLPOfStake(stake);
			_amounts[3] += stake.amount;

			// Mark this stake as withdrawn and remove its index from the active list
			stake.withdrawn = true;
			_removeActiveIndex(sender, index);
		}

		// Interact with external contracts to complete the withdrawal process
		if (_amounts[1] > 0) {
			// Mint rewards tokens if necessary
			tokenManager.mintOrTransferByPool(sender, _amounts[1]);
		}

		// the calculation is amountToBurn = total withdraw weight - total withdraw amount;
		uint256 amountToBurn = _amounts[3] - _amounts[1];

		// Mint WINR tokens to decrease total supply
		if (amountToBurn > 0) {
			// this code piece is used to decrease burn amount from WINR total supply
			// Mint WINR tokens to the tokenManager contract
			tokenManager.mintWINR(address(tokenManager), amountToBurn);
			tokenManager.burnWINR(amountToBurn);
		}

		// Burn total vested WINR tokens
		tokenManager.burnVestedWINR(_amounts[3]);

		// Update the total weight and total staked amount
		totalWeight -= _amounts[0];
		totalStakedVestedWINR -= _amounts[3];

		// Claim rewards for remaining stakes
		_claim(indexes, false);

		// Emit an event to log the withdrawal
		emit WithdrawBatch(
			sender,
			block.timestamp,
			indexes,
			_amounts[1],
			_amounts[1],
			_amounts[3]
		);
	}

	/*================================================= Internal Functions =======================================================*/
	/**
	 * @dev Claims the reward for the specified stakes
	 * @param indexes Array of the indexes to claim
	 * @param isClaim Checks if the caller is the claim function
	 */
	function _claim(uint256[] memory indexes, bool isClaim) internal {
		address sender_ = msg.sender;
		uint256 totalFee_;

		// Check
		for (uint256 i = 0; i < indexes.length; i++) {
			uint256 index_ = indexes[i];

			StakeVesting storage stake_ = stakes[sender_][index_];

			// Check that the stake has not been withdrawn
			if (isClaim) {
				require(!stake_.withdrawn, "Stake has already been withdrawn");
			}

			// Check that the stake has not been cancelled
			require(!stake_.cancelled, "Stake has been cancelled");

			 uint256 fee_ = _pendingWLPOfStake(stake_);
			 stake_.profitDebt += fee_;
			totalFee_ += fee_;
			 
		}
		// Effects


		totalProfit -= totalFee_;
		totalClaimed[sender_] += totalFee_;
		// Interactions
		if (totalFee_ > 0) {
			
			tokenManager.sendWLP(sender_, totalFee_);
		}

		// Emit event
		emit ClaimVestingBatch(sender_, totalFee_, indexes);
	}

	/**
	 *
	 *  @dev Internal function to remove an active vesting index for a staker.
	 *  @param staker The address of the staker.
	 *  @param index The index of the vesting schedule to remove.
	 */
	function _removeActiveIndex(address staker, uint index) internal {
		uint[] storage indexes = activeVestingIndexes[staker];

    	uint length = indexes.length;

    	// Find the index to remove
    	for (uint i = 0; i < length; i++) {
        	if (indexes[i] == index) {
            	// Swap with the last element
            	indexes[i] = indexes[length - 1];
            
            	// Remove the last element
            	indexes.pop();
            	return;
        	}
    	}
	}

	function _addActiveIndex(address staker, uint256 index) internal {
		uint[] storage indexes;

		indexes = activeVestingIndexes[staker];
		indexes.push(index);
	}

	function share(uint256 amount) external virtual override {}
}

File 3 of 12 : ReentrancyGuard.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Gas optimized reentrancy protection for smart contracts.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ReentrancyGuard.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol)
abstract contract ReentrancyGuard {
    uint256 private locked = 1;

    modifier nonReentrant() virtual {
        require(locked == 1, "REENTRANCY");

        locked = 2;

        _;

        locked = 1;
    }
}

File 4 of 12 : Pausable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        _requireNotPaused();
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        _requirePaused();
        _;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Throws if the contract is paused.
     */
    function _requireNotPaused() internal view virtual {
        require(!paused(), "Pausable: paused");
    }

    /**
     * @dev Throws if the contract is not paused.
     */
    function _requirePaused() internal view virtual {
        require(paused(), "Pausable: not paused");
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

File 5 of 12 : AccessControlBase.sol
// SPDX-License-Identifier: MIT

import "@openzeppelin/contracts/utils/Context.sol";
import "../interfaces/core/IVaultAccessControlRegistry.sol";

pragma solidity 0.8.19;

contract AccessControlBase is Context {
	IVaultAccessControlRegistry public immutable registry;
	address public immutable timelockAddressImmutable;

	constructor(address _vaultRegistry, address _timelock) {
		registry = IVaultAccessControlRegistry(_vaultRegistry);
		timelockAddressImmutable = _timelock;
	}

	/*==================== Managed in VaultAccessControlRegistry *====================*/

	modifier onlyGovernance() {
		require(registry.isCallerGovernance(_msgSender()), "Forbidden: Only Governance");
		_;
	}

	modifier onlyEmergency() {
		require(registry.isCallerEmergency(_msgSender()), "Forbidden: Only Emergency");
		_;
	}

	modifier onlySupport() {
		require(registry.isCallerSupport(_msgSender()), "Forbidden: Only Support");
		_;
	}

	modifier onlyTeam() {
		require(registry.isCallerTeam(_msgSender()), "Forbidden: Only Team");
		_;
	}

	modifier onlyProtocol() {
		require(registry.isCallerProtocol(_msgSender()), "Forbidden: Only Protocol");
		_;
	}

	modifier protocolNotPaused() {
		require(!registry.isProtocolPaused(), "Forbidden: Protocol Paused");
		_;
	}

	/*==================== Managed in WINRTimelock *====================*/

	modifier onlyTimelockGovernance() {
		address timelockActive_;
		if (!registry.timelockActivated()) {
			// the flip is not switched yet, so this means that the governance address can still pass the onlyTimelockGoverance modifier
			timelockActive_ = registry.governanceAddress();
		} else {
			// the flip is switched, the immutable timelock is now locked in as the only adddress that can pass this modifier (and nothing can undo that)
			timelockActive_ = timelockAddressImmutable;
		}
		require(_msgSender() == timelockActive_, "Forbidden: Only TimelockGovernance");
		_;
	}
}

File 6 of 12 : ITokenManager.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

interface ITokenManager {
	function takeVestedWINR(address _from, uint256 _amount) external;

	function takeWINR(address _from, uint256 _amount) external;

	function sendVestedWINR(address _to, uint256 _amount) external;

	function sendWINR(address _to, uint256 _amount) external;

	function burnVestedWINR(uint256 _amount) external;

	function burnWINR(uint256 _amount) external;

	function mintWINR(address _to, uint256 _amount) external;

	function sendWLP(address _to, uint256 _amount) external;

	function mintOrTransferByPool(address _to, uint256 _amount) external;

	function mintVestedWINR(address _input, uint256 _amount, address _recipient) external returns(uint256 _mintAmount);

	function mintedByGames() external returns (uint256);

	function MAX_MINT() external returns (uint256);

	function share(uint256 amount) external;
}

File 7 of 12 : IWINR.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

interface IWINR is IERC20 {
	function mint(address account, uint256 amount) external returns (uint256, uint256);

	function burn(uint256 amount) external;

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

File 8 of 12 : IWINRStaking.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

interface IWINRStaking {
	function share(uint256 amount) external;

	function totalWeight() external view returns (uint256);

	struct StakeDividend {
		uint256 amount;
		uint256 profitDebt;
		uint256 weight;
		uint128 depositTime;
	}

	struct StakeVesting {
		uint256 amount; // The amount of tokens being staked
		uint256 weight; // The weight of the stake, used for calculating rewards
		uint256 vestingDuration; // The duration of the vesting period in seconds
		uint256 profitDebt; // The amount of profit earned by the stake, used for calculating rewards
		uint256 startTime; // The timestamp at which the stake was created
		uint256 accTokenFirstDay; // The accumulated  WINR tokens earned on the first day of the stake
		uint256 accTokenPerDay; // The rate at which WINR tokens are accumulated per day
		bool withdrawn; // Indicates whether the stake has been withdrawn or not
		bool cancelled; // Indicates whether the stake has been cancelled or not
	}

	struct Period {
		uint256 duration;
		uint256 minDuration;
		uint256 claimDuration;
		uint256 minPercent;
	}

	struct WeightMultipliers {
		uint256 winr;
		uint256 vWinr;
		uint256 vWinrVesting;
	}

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

	event Donation(address indexed player, uint amount);
	event Share(uint256 amount, uint256 totalWeight, uint256 totalStakedVWINR, uint256 totalStakedWINR);
	event DepositVesting(
		address indexed user,
		uint256 index,
		uint256 startTime,
		uint256 endTime,
		uint256 amount,
		uint256 profitDebt,
		bool isVested,
		bool isVesting
	);

	event DepositDividend(
		address indexed user,
		uint256 amount,
		uint256 profitDebt,
		bool isVested
	);
	event Withdraw(
		address indexed user,
		uint256 withdrawTime,
		uint256 index,
		uint256 amount,
		uint256 redeem,
		uint256 vestedBurn
	);
	event WithdrawBatch(
		address indexed user,
		uint256 withdrawTime,
		uint256[] indexes,
		uint256 amount,
		uint256 redeem,
		uint256 vestedBurn
	);

	event Unstake(
		address indexed user,
		uint256 unstakeTime,
		uint256 amount,
		uint256 burnedAmount,
		bool isVested
	);
	event Cancel(
		address indexed user,
		uint256 cancelTime,
		uint256 index,
		uint256 burnedAmount,
		uint256 sentAmount
	);
	event ClaimVesting(address indexed user, uint256 reward, uint256 index);
	event ClaimVestingBatch(address indexed user, uint256 reward, uint256[] indexes);
	event ClaimDividend(address indexed user, uint256 reward, bool isVested);
	event ClaimDividendBatch(address indexed user, uint256 reward);
	event WeightMultipliersUpdate(WeightMultipliers _weightMultipliers);
	event UnstakeBurnPercentageUpdate(uint256 _unstakeBurnPercentage);
}

File 9 of 12 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.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 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.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 10 of 12 : IVaultAccessControlRegistry.sol
// SPDX-License-Identifier: MIT

import "@openzeppelin/contracts/access/IAccessControl.sol";

pragma solidity >=0.6.0 <0.9.0;

interface IVaultAccessControlRegistry is IAccessControl {
	function timelockActivated() external view returns (bool);

	function governanceAddress() external view returns (address);

	function pauseProtocol() external;

	function unpauseProtocol() external;

	function isCallerGovernance(address _account) external view returns (bool);

	function isCallerEmergency(address _account) external view returns (bool);

	function isCallerProtocol(address _account) external view returns (bool);

	function isCallerTeam(address _account) external view returns (bool);

	function isCallerSupport(address _account) external view returns (bool);

	function isProtocolPaused() external view returns (bool);

	function changeGovernanceAddress(address _governanceAddress) external;

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

	event DeadmanSwitchFlipped();
	event GovernanceChange(address newGovernanceAddress);
}

File 11 of 12 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @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);

    /**
     * @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 `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, 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 `from` to `to` 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 from,
        address to,
        uint256 amount
    ) external returns (bool);
}

File 12 of 12 : IAccessControl.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)

pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}

Settings
{
  "remappings": [
    "@ensdomains/=node_modules/@ensdomains/",
    "@openzeppelin/=node_modules/@openzeppelin/",
    "@uniswap/=node_modules/@uniswap/",
    "base64-sol/=node_modules/base64-sol/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "eth-gas-reporter/=node_modules/eth-gas-reporter/",
    "forge-std/=lib/forge-std/src/",
    "hardhat/=node_modules/hardhat/",
    "solmate/=node_modules/solmate/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "libraries": {}
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"_vaultRegistry","type":"address"},{"internalType":"address","name":"_timelock","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"cancelTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"burnedAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sentAmount","type":"uint256"}],"name":"Cancel","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isVested","type":"bool"}],"name":"ClaimDividend","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"ClaimDividendBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"ClaimVesting","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"indexes","type":"uint256[]"}],"name":"ClaimVestingBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"profitDebt","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isVested","type":"bool"}],"name":"DepositDividend","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"profitDebt","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isVested","type":"bool"},{"indexed":false,"internalType":"bool","name":"isVesting","type":"bool"}],"name":"DepositVesting","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"player","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Donation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalWeight","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalStakedVWINR","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalStakedWINR","type":"uint256"}],"name":"Share","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"unstakeTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"burnedAmount","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isVested","type":"bool"}],"name":"Unstake","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_unstakeBurnPercentage","type":"uint256"}],"name":"UnstakeBurnPercentageUpdate","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint256","name":"winr","type":"uint256"},{"internalType":"uint256","name":"vWinr","type":"uint256"},{"internalType":"uint256","name":"vWinrVesting","type":"uint256"}],"indexed":false,"internalType":"struct IWINRStaking.WeightMultipliers","name":"_weightMultipliers","type":"tuple"}],"name":"WeightMultipliersUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"withdrawTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"redeem","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"vestedBurn","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"withdrawTime","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"indexes","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"redeem","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"vestedBurn","type":"uint256"}],"name":"WithdrawBatch","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"accumProfitPerWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"activeVestingIndexes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"cancel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimDividend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"indexes","type":"uint256[]"}],"name":"claimVesting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"_isVested","type":"bool"}],"name":"depositDividend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"vestingDuration","type":"uint256"}],"name":"depositVesting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"bool","name":"_isVested","type":"bool"}],"name":"dividendStakedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"dividendVestedWINRStakes","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"profitDebt","type":"uint256"},{"internalType":"uint256","name":"weight","type":"uint256"},{"internalType":"uint128","name":"depositTime","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"dividendWINRStakes","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"profitDebt","type":"uint256"},{"internalType":"uint256","name":"weight","type":"uint256"},{"internalType":"uint128","name":"depositTime","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"staker","type":"address"}],"name":"getActiveIndexes","outputs":[{"internalType":"uint256[]","name":"indexes","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"bool","name":"_isVested","type":"bool"}],"name":"getDividendStake","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"profitDebt","type":"uint256"},{"internalType":"uint256","name":"weight","type":"uint256"},{"internalType":"uint128","name":"depositTime","type":"uint128"}],"internalType":"struct IWINRStaking.StakeDividend","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getVestingStake","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"weight","type":"uint256"},{"internalType":"uint256","name":"vestingDuration","type":"uint256"},{"internalType":"uint256","name":"profitDebt","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"accTokenFirstDay","type":"uint256"},{"internalType":"uint256","name":"accTokenPerDay","type":"uint256"},{"internalType":"bool","name":"withdrawn","type":"bool"},{"internalType":"bool","name":"cancelled","type":"bool"}],"internalType":"struct IWINRStaking.StakeVesting","name":"_stake","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getVestingStakeLength","outputs":[{"internalType":"uint256","name":"_length","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"globalData","outputs":[{"internalType":"uint256","name":"_totalStakedVWINR","type":"uint256"},{"internalType":"uint256","name":"_totalStakedWINR","type":"uint256"},{"internalType":"uint256","name":"_totalEarned","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"pendingDividendRewards","outputs":[{"internalType":"uint256","name":"pending_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"pendingVestingByIndex","outputs":[{"internalType":"uint256","name":"pending","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"pendingVestingRewards","outputs":[{"internalType":"uint256","name":"pending","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"period","outputs":[{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"minDuration","type":"uint256"},{"internalType":"uint256","name":"claimDuration","type":"uint256"},{"internalType":"uint256","name":"minPercent","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"registry","outputs":[{"internalType":"contract IVaultAccessControlRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ITokenManager","name":"_tokenManager","type":"address"}],"name":"setTokenManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_unstakeBurnPercentage","type":"uint256"}],"name":"setUnstakeBurnPercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"share","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"stakes","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"weight","type":"uint256"},{"internalType":"uint256","name":"vestingDuration","type":"uint256"},{"internalType":"uint256","name":"profitDebt","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"accTokenFirstDay","type":"uint256"},{"internalType":"uint256","name":"accTokenPerDay","type":"uint256"},{"internalType":"bool","name":"withdrawn","type":"bool"},{"internalType":"bool","name":"cancelled","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timelockAddressImmutable","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenManager","outputs":[{"internalType":"contract ITokenManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"totalClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalEarned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalProfit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStakedVestedWINR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStakedWINR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"_isVested","type":"bool"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unstakeBurnPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"minDuration","type":"uint256"},{"internalType":"uint256","name":"claimDuration","type":"uint256"},{"internalType":"uint256","name":"minPercent","type":"uint256"}],"name":"updatePeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256[]","name":"_indexes","type":"uint256[]"}],"name":"vestingStakedAmount","outputs":[{"internalType":"uint256","name":"_totalStaked","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weightMultipliers","outputs":[{"internalType":"uint256","name":"winr","type":"uint256"},{"internalType":"uint256","name":"vWinr","type":"uint256"},{"internalType":"uint256","name":"vWinrVesting","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawDonations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"withdrawVesting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"indexes","type":"uint256[]"}],"name":"withdrawVestingBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"withdrawableTokens","outputs":[{"internalType":"uint256","name":"_withdrawable","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

600180805562ed4e0060c08190526213c68060e081905260a56101008190526706f05b59d3b20000610120819052600d93909355600e91909155600f556010556101a0604052610140819052600261016081905261018082905260118290556012556013553480156200007157600080fd5b5060405162004464380380620044648339810160408190526200009491620000de565b6000805460ff191690556001600160a01b039182166080521660a0526611c37937e0800060075562000116565b80516001600160a01b0381168114620000d957600080fd5b919050565b60008060408385031215620000f257600080fd5b620000fd83620000c1565b91506200010d60208401620000c1565b90509250929050565b60805160a0516142f76200016d600039600061086201526000818161063201528181610e5201528181610ffe015281816112af01528181611d4b015281816120d8015281816122120152612e2301526142f76000f3fe60806040526004361061026b5760003560e01c80637cb2b79c11610144578063b9e8346d116100b6578063ef5d9ae81161007a578063ef5d9ae81461091a578063ef78d4fd14610947578063f0fc6bca1461098a578063f520c87f1461099f578063f79d032d146109b5578063fe9b050e146109cb576102a8565b8063b9e8346d14610850578063c3d9c4b414610884578063dba41cbf146108a4578063e4aff9c4146108c4578063e982a482146108fa576102a8565b806396c82e571161010857806396c82e571461076f5780639def0543146107855780639ebea88c146107a5578063a9c26186146107c5578063ae03119314610810578063b1945e5a14610830576102a8565b80637cb2b79c146106e55780638456cb5914610705578063860015191461071a578063947a56cd14610730578063961072021461074f576102a8565b8063581b593e116101dd578063613ce410116101a1578063613ce410146105a25780636230b83d146105d45780636cc0bd24146105ea5780636dfa8d991461060a5780637b103999146106205780637be25ba214610654576102a8565b8063581b593e14610463578063584b62a1146104d75780635ab08f001461053f5780635c975abb1461055f57806360d3bdfe14610582576102a8565b80632a709b141161022f5780632a709b14146103965780632ef73e88146103ce578063374756f5146103ee5780633f4ba83a1461040e57806340e58ee5146104235780634178ec2814610443576102a8565b80630210290f146102da5780631df0af3f1461031057806324d17fa11461033257806327f00c251461035257806329f0db2214610376576102a8565b366102a85760405134815233907f5d8bc849764969eb1bcc6d0a2f55999d0167c1ccec240a4f39cf664ca9c4148e906020015b60405180910390a2005b60405134815233907f5d8bc849764969eb1bcc6d0a2f55999d0167c1ccec240a4f39cf664ca9c4148e9060200161029e565b3480156102e657600080fd5b506102fa6102f5366004613e82565b610a27565b6040516103079190613eda565b60405180910390f35b34801561031c57600080fd5b5061033061032b366004613eed565b610a93565b005b34801561033e57600080fd5b5061033061034d366004613f0f565b610e48565b34801561035e57600080fd5b5061036860055481565b604051908152602001610307565b34801561038257600080fd5b50610330610391366004613f41565b610ff4565b3480156103a257600080fd5b506009546103b6906001600160a01b031681565b6040516001600160a01b039091168152602001610307565b3480156103da57600080fd5b506103686103e9366004613e82565b6110e3565b3480156103fa57600080fd5b50610330610409366004613fa6565b6111f2565b34801561041a57600080fd5b506103306112a5565b34801561042f57600080fd5b5061033061043e366004613f41565b61138a565b34801561044f57600080fd5b5061033061045e366004613f41565b6116d7565b34801561046f57600080fd5b506104ae61047e366004613e82565b6014602052600090815260409020805460018201546002830154600390930154919290916001600160801b031684565b604080519485526020850193909352918301526001600160801b03166060820152608001610307565b3480156104e357600080fd5b506104f76104f2366004613fe8565b611cd3565b60408051998a5260208a0198909852968801959095526060870193909352608086019190915260a085015260c0840152151560e0830152151561010082015261012001610307565b34801561054b57600080fd5b5061033061055a366004613fe8565b611d41565b34801561056b57600080fd5b5060005460ff166040519015158152602001610307565b34801561058e57600080fd5b5061036861059d366004614022565b611ed6565b3480156105ae57600080fd5b506005546004546008545b60408051938452602084019290925290820152606001610307565b3480156105e057600080fd5b5061036860075481565b3480156105f657600080fd5b5061036861060536600461405b565b611f1e565b34801561061657600080fd5b5061036860085481565b34801561062c57600080fd5b506103b67f000000000000000000000000000000000000000000000000000000000000000081565b34801561066057600080fd5b5061067461066f366004613fe8565b612016565b6040516103079190600061012082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e0830151151560e0830152610100808401511515818401525092915050565b3480156106f157600080fd5b50610330610700366004613e82565b6120ce565b34801561071157600080fd5b50610330612208565b34801561072657600080fd5b5061036860025481565b34801561073c57600080fd5b506011546012546013546105b992919083565b34801561075b57600080fd5b5061036861076a366004613e82565b6122eb565b34801561077b57600080fd5b5061036860035481565b34801561079157600080fd5b506103686107a0366004613fe8565b6123b9565b3480156107b157600080fd5b506103306107c03660046140b0565b6123ea565b3480156107d157600080fd5b506104ae6107e0366004613e82565b6015602052600090815260409020805460018201546002830154600390930154919290916001600160801b031684565b34801561081c57600080fd5b5061033061082b366004613fa6565b612770565b34801561083c57600080fd5b5061036861084b366004613fe8565b612d18565b34801561085c57600080fd5b506103b67f000000000000000000000000000000000000000000000000000000000000000081565b34801561089057600080fd5b5061033061089f366004613f41565b612df8565b3480156108b057600080fd5b506103686108bf366004613fe8565b612fbf565b3480156108d057600080fd5b506103686108df366004613e82565b6001600160a01b03166000908152600a602052604090205490565b34801561090657600080fd5b506103306109153660046140b0565b6130a2565b34801561092657600080fd5b50610368610935366004613e82565b600c6020526000908152604090205481565b34801561095357600080fd5b50600d54600e54600f5460105461096a9392919084565b604080519485526020850193909352918301526060820152608001610307565b34801561099657600080fd5b5061033061332e565b3480156109ab57600080fd5b5061036860065481565b3480156109c157600080fd5b5061036860045481565b3480156109d757600080fd5b506109eb6109e6366004614022565b61336d565b60405161030791908151815260208083015190820152604080830151908201526060918201516001600160801b03169181019190915260800190565b6001600160a01b0381166000908152600b6020908152604091829020805483518184028101840190945280845260609392830182828015610a8757602002820191906000526020600020905b815481526020019060010190808311610a73575b50505050509050919050565b8160008111610abd5760405162461bcd60e51b8152600401610ab4906140d5565b60405180910390fd5b600154600114610adf5760405162461bcd60e51b8152600401610ab49061410a565b6002600155610aec61341b565b6000610afb8362015180614144565b600e549091508110801590610b125750600d548311155b610b5e5760405162461bcd60e51b815260206004820152601a60248201527f6475726174696f6e206d75737420626520696e20706572696f640000000000006044820152606401610ab4565b336000610b6d86600180613461565b90506000610b7a8261349a565b6010549091504290600090670de0b6b3a764000090610b99908b614144565b610ba3919061415b565b600f54909150600090610bb6838c61417d565b610bc0919061415b565b60095460405163079b9d7760e21b81529192506001600160a01b031690631e6e75dc90610bf39089908e90600401614190565b600060405180830381600087803b158015610c0d57600080fd5b505af1158015610c21573d6000803e3d6000fd5b505050508460036000828254610c3791906141a9565b925050819055508960056000828254610c5091906141a9565b92505081905550600a6000876001600160a01b03166001600160a01b031681526020019081526020016000206040518061012001604052808c8152602001878152602001898152602001868152602001858152602001848152602001838152602001600015158152602001600015158152509080600181540180825580915050600190039060005260206000209060080201600090919091909150600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e08201518160070160006101000a81548160ff0219169083151502179055506101008201518160070160016101000a81548160ff021916908315150217905550505060006001600a6000336001600160a01b03166001600160a01b0316815260200190815260200160002080549050610dab919061417d565b336000908152600b602090815260408220805460018101825590835291200181905590506040805182815260208101869052908101899052606081018c905260808101869052600160a0820181905260c08201526001600160a01b038816907feb7bdad6029ad027c77906ce1960c5ac2111bf37b5a7bb7b63068aa4f25256179060e00160405180910390a2505060018055505050505050505050565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016637d075595336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610ebc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee091906141bc565b610efc5760405162461bcd60e51b8152600401610ab4906141d9565b82841015610f725760405162461bcd60e51b815260206004820152603a60248201527f4475726174696f6e206d7573742062652067726561746572207468616e206f7260448201527f20657175616c20746f206d696e696d756d206475726174696f6e0000000000006064820152608401610ab4565b83821115610fe05760405162461bcd60e51b815260206004820152603560248201527f436c61696d206475726174696f6e206d757374206265206c657373207468616e6044820152741037b91032b8bab0b6103a3790323ab930ba34b7b760591b6064820152608401610ab4565b600d93909355600e91909155600f55601055565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016637d075595336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015611068573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061108c91906141bc565b6110a85760405162461bcd60e51b8152600401610ab4906141d9565b60078190556040518181527fc6723167dfc6a0204d07a4d7c81104295b948a8fac5769b1576c202032cf8ef39060200160405180910390a150565b6000806110ef83610a27565b905060005b81518110156111eb576001600160a01b0384166000908152600a60205260408120835184908490811061112957611129614210565b60200260200101518154811061114157611141614210565b600091825260209182902060408051610120810182526008909302909101805483526001810154938301939093526002830154908201526003820154606082015260048201546080820152600582015460a0820152600682015460c082015260079091015460ff808216151560e0840152610100918290041615159082015290506111cb816134bd565b6111d590856141a9565b93505080806111e390614226565b9150506110f4565b5050919050565b6111fa61341b565b60015460011461121c5760405162461bcd60e51b8152600401610ab49061410a565b60026001558061125e5760405162461bcd60e51b815260206004820152600d60248201526c656d70747920696e646578657360981b6044820152606401610ab4565b61129d82828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525060019250613510915050565b505060018055565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663784cbca2336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015611319573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061133d91906141bc565b6113805760405162461bcd60e51b8152602060048201526014602482015273466f7262696464656e3a204f6e6c79205465616d60601b6044820152606401610ab4565b6113886137e8565b565b33611393613dfc565b61139d8284612016565b90508060e00151156113e75760405162461bcd60e51b815260206004820152601360248201527239ba30b5b2903430b9903bb4ba34323930bbb760691b6044820152606401610ab4565b806101000151156114305760405162461bcd60e51b81526020600482015260136024820152721cdd185ad9481a185cc818d85b98d95b1b1959606a1b6044820152606401610ab4565b61143a828461383a565b805160006114478261390f565b90506000611455828461417d565b90508260056000828254611469919061417d565b909155505060208401516003805460009061148590849061417d565b9091555060009050611496856134bd565b90508015611526576003546114b3670de0b6b3a764000083614144565b6114bd919061415b565b600660008282546114ce91906141a9565b90915550506001600160a01b0386166000908152600a6020526040902080548291908990811061150057611500614210565b9060005260206000209060080201600301600082825461152091906141a9565b90915550505b6001600160a01b0386166000908152600a602052604090208054600191908990811061155457611554614210565b6000918252602080832060076008909302019190910180549315156101000261ff0019909416939093179092556001600160a01b0388168152600a909152604081208054899081106115a8576115a8614210565b600091825260209091206008909102015560095460405163d3e96ed360e01b81526001600160a01b039091169063d3e96ed3906115eb9089908690600401614190565b600060405180830381600087803b15801561160557600080fd5b505af1158015611619573d6000803e3d6000fd5b50506009546040516376555fed60e11b8152600481018790526001600160a01b03909116925063ecaabfda9150602401600060405180830381600087803b15801561166357600080fd5b505af1158015611677573d6000803e3d6000fd5b505060408051428152602081018b9052908101869052606081018590526001600160a01b03891692507f10de281942f9db9a7f40110d5f1d818f2ab6f7e182a6d5c0727c6804c17b84bf915060800160405180910390a250505050505050565b6116df61341b565b6001546001146117015760405162461bcd60e51b8152600401610ab49061410a565b6002600155336000818152600a6020526040812080548490811061172757611727614210565b906000526020600020906008020190508060020154816004015461174b91906141a9565b42101561179a5760405162461bcd60e51b815260206004820181905260248201527f596f752063616e277420776974686472617720746865207374616b65207965746044820152606401610ab4565b600781015460ff16156117e35760405162461bcd60e51b815260206004820152601160248201527030b63932b0b23c903bb4ba34323930bbb760791b6044820152606401610ab4565b6007810154610100900460ff161561182f5760405162461bcd60e51b815260206004820152600f60248201526e1cdd185ad94818d85b98d95b1b1959608a1b6044820152606401610ab4565b604080516101208101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460ff808216151560e084015261010091829004161515908201526000906118a790613928565b604080516101208101825284548152600185015460208201526002850154918101919091526003840154606082015260048401546080820152600584015460a0820152600684015460c0820152600784015460ff808216151560e08401526101009182900416151590820152909150600090611922906134bd565b9050811561198f5760095460405163e24acd4b60e01b81526001600160a01b039091169063e24acd4b9061195c9087908690600401614190565b600060405180830381600087803b15801561197657600080fd5b505af115801561198a573d6000803e3d6000fd5b505050505b825460009061199f90849061417d565b90508015611a6a57600954604051633802f5af60e11b81526001600160a01b0390911690637005eb5e906119d99083908590600401614190565b600060405180830381600087803b1580156119f357600080fd5b505af1158015611a07573d6000803e3d6000fd5b505060095460405163673b31a760e01b8152600481018590526001600160a01b03909116925063673b31a79150602401600060405180830381600087803b158015611a5157600080fd5b505af1158015611a65573d6000803e3d6000fd5b505050505b60095484546040516376555fed60e11b81526001600160a01b039092169163ecaabfda91611a9e9160040190815260200190565b600060405180830381600087803b158015611ab857600080fd5b505af1158015611acc573d6000803e3d6000fd5b505050506000821115611c19576009546040516301e2206160e11b81526001600160a01b03909116906303c440c290611b0b9088908690600401614190565b600060405180830381600087803b158015611b2557600080fd5b505af1158015611b39573d6000803e3d6000fd5b5050506001600160a01b0386166000908152600a60205260409020805484925088908110611b6957611b69614210565b90600052602060002090600802016003016000828254611b8991906141a9565b925050819055508160026000828254611ba2919061417d565b90915550506001600160a01b0385166000908152600c602052604081208054849290611bcf9084906141a9565b909155505060408051838152602081018890526001600160a01b038716917f93b2b5baeb90867d00d09e02023eed58ae019d05b1c254578512984cc85e5ba6910160405180910390a25b60078401805460ff19166001179055611c32858761383a565b836001015460036000828254611c48919061417d565b9091555050835460058054600090611c6190849061417d565b90915550506001840154845460408051428152602081018a9052908101839052606081019290925260808201526001600160a01b038616907fb7ee00edafdb5db3a1b52a5789a6b562eb48268842d113dbfe860b6f86e5f5959060a0015b60405180910390a250506001805550505050565b600a6020528160005260406000208181548110611cef57600080fd5b6000918252602090912060089091020180546001820154600283015460038401546004850154600586015460068701546007909701549598509396509194909391929160ff8082169161010090041689565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016637d075595336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015611db5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dd991906141bc565b611df55760405162461bcd60e51b8152600401610ab4906141d9565b80471015611e3c5760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b6044820152606401610ab4565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611e89576040519150601f19603f3d011682016040523d82523d6000602084013e611e8e565b606091505b5050905080611ed15760405162461bcd60e51b815260206004820152600f60248201526e15da5d1a191c985dc819985a5b1959608a1b6044820152606401610ab4565b505050565b600081611efb576001600160a01b038316600090815260146020526040902054611f15565b6001600160a01b0383166000908152601560205260409020545b90505b92915050565b6000805b8281101561200e576001600160a01b0385166000908152600a60205260408120858584818110611f5457611f54614210565b9050602002013581548110611f6b57611f6b614210565b60009182526020918290206040805161012081018252600890930290910180548084526001820154948401949094526002810154918301919091526003810154606083015260048101546080830152600581015460a0830152600681015460c08301526007015460ff808216151560e084015261010091829004161515908201529150611ff890846141a9565b925050808061200690614226565b915050611f22565b509392505050565b61201e613dfc565b6001600160a01b0383166000908152600a6020526040902080548390811061204857612048614210565b600091825260209182902060408051610120810182526008909302909101805483526001810154938301939093526002830154908201526003820154606082015260048201546080820152600582015460a0820152600682015460c082015260079091015460ff808216151560e084015261010091829004161515908201529392505050565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016637d075595336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015612142573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061216691906141bc565b6121825760405162461bcd60e51b8152600401610ab4906141d9565b6001600160a01b0381166121e65760405162461bcd60e51b815260206004820152602560248201527f746f6b656e206d616e6167657220616464726573732063616e206e6f74206265604482015264207a65726f60d81b6064820152608401610ab4565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663784cbca2336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa15801561227c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122a091906141bc565b6122e35760405162461bcd60e51b8152602060048201526014602482015273466f7262696464656e3a204f6e6c79205465616d60601b6044820152606401610ab4565b6113886139e7565b6001600160a01b0381166000908152601560209081526040808320815160808101835281548152600182015493810193909352600281015491830191909152600301546001600160801b0316606082015261234590613a24565b61234f90826141a9565b6001600160a01b0383166000908152601460209081526040918290208251608081018452815481526001820154928101929092526002810154928201929092526003909101546001600160801b031660608201529091506123af90613a24565b611f1890826141a9565b600b60205281600052604060002081815481106123d557600080fd5b90600052602060002001600091509150505481565b60015460011461240c5760405162461bcd60e51b8152600401610ab49061410a565b600260015561241961341b565b3360008261243e576001600160a01b0382166000908152601460205260409020612457565b6001600160a01b03821660009081526015602052604090205b905083816000015410156124ad5760405162461bcd60e51b815260206004820152601960248201527f496e73756666696369656e74207374616b6520616d6f756e74000000000000006044820152606401610ab4565b6009546001600160a01b031660006124c48661390f565b905060006124d2828861417d565b905060006124e08688613a70565b5086156125ce576040516376555fed60e11b8152600481018490526001600160a01b0385169063ecaabfda90602401600060405180830381600087803b15801561252957600080fd5b505af115801561253d573d6000803e3d6000fd5b505060405163d3e96ed360e01b81526001600160a01b038716925063d3e96ed3915061256f9089908690600401614190565b600060405180830381600087803b15801561258957600080fd5b505af115801561259d573d6000803e3d6000fd5b50506012546125af9250905089614144565b905087600560008282546125c3919061417d565b909155506126b09050565b60405163673b31a760e01b8152600481018490526001600160a01b0385169063673b31a790602401600060405180830381600087803b15801561261057600080fd5b505af1158015612624573d6000803e3d6000fd5b505060405163562084bd60e11b81526001600160a01b038716925063ac41097a91506126569089908690600401614190565b600060405180830381600087803b15801561267057600080fd5b505af1158015612684573d6000803e3d6000fd5b50506011546126969250905089614144565b905087600460008282546126aa919061417d565b90915550505b80600360008282546126c2919061417d565b90915550508454889086906000906126db90849061417d565b92505081905550808560020160008282546126f6919061417d565b909155505060028501546127099061349a565b6001860155604080514281526020810184905290810184905287151560608201526001600160a01b038716907fc7ccdcb2d25f572c6814e377dbb34ea4318a4b7d3cd890f5cfad699d75327c7c9060800160405180910390a2505060018055505050505050565b61277861341b565b60015460011461279a5760405162461bcd60e51b8152600401610ab49061410a565b6002600155336127a8613e4c565b60005b83811015612a7d5760008585838181106127c7576127c7614210565b9050602002013590506000600a6000866001600160a01b03166001600160a01b03168152602001908152602001600020828154811061280857612808614210565b906000526020600020906008020190508060020154816004015461282c91906141a9565b42101561287b5760405162461bcd60e51b815260206004820181905260248201527f596f752063616e277420776974686472617720746865207374616b65207965746044820152606401610ab4565b600781015460ff16156128c45760405162461bcd60e51b815260206004820152601160248201527030b63932b0b23c903bb4ba34323930bbb760791b6044820152606401610ab4565b6007810154610100900460ff16156129105760405162461bcd60e51b815260206004820152600f60248201526e1cdd185ad94818d85b98d95b1b1959608a1b6044820152606401610ab4565b6001810154845185906129249083906141a9565b905250604080516101208101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460ff808216151560e0840152610100918290041615159082015261299c90613928565b6020850180516129ad9083906141a9565b905250604080516101208101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460ff808216151560e08401526101009182900416151590820152612a25906134bd565b604085018051612a369083906141a9565b9052508054606085018051612a4c9083906141a9565b90525060078101805460ff19166001179055612a68858361383a565b50508080612a7590614226565b9150506127ab565b50602081015115612af157600954602082015160405163e24acd4b60e01b81526001600160a01b039092169163e24acd4b91612abe91869190600401614190565b600060405180830381600087803b158015612ad857600080fd5b505af1158015612aec573d6000803e3d6000fd5b505050505b60208101516060820151600091612b079161417d565b90508015612bd257600954604051633802f5af60e11b81526001600160a01b0390911690637005eb5e90612b419083908590600401614190565b600060405180830381600087803b158015612b5b57600080fd5b505af1158015612b6f573d6000803e3d6000fd5b505060095460405163673b31a760e01b8152600481018590526001600160a01b03909116925063673b31a79150602401600060405180830381600087803b158015612bb957600080fd5b505af1158015612bcd573d6000803e3d6000fd5b505050505b60095460608301516040516376555fed60e11b815260048101919091526001600160a01b039091169063ecaabfda90602401600060405180830381600087803b158015612c1e57600080fd5b505af1158015612c32573d6000803e3d6000fd5b5050505081600060048110612c4957612c49614210565b602002015160036000828254612c5f919061417d565b9091555050606082015160058054600090612c7b90849061417d565b90915550506040805160208087028281018201909352868252612cb99288918891829185019084908082843760009201829052509250613510915050565b602082015160608301516040516001600160a01b038616927f670058fd657dd0cbca748af3a687a4d5b441b61753a2ccbea58894eac13d559992612d059242928b928b9282919061423f565b60405180910390a2505060018055505050565b6001600160a01b0382166000908152600a60205260408120805482919084908110612d4557612d45614210565b600091825260209182902060408051610120810182526008909302909101805483526001810154938301939093526002830154908201526003820154606082015260048201546080820152600582015460a0820152600682015460c082015260079091015460ff808216151560e084015261010091829004161515908201529050612dcf81613928565b91504281604001518260800151612de691906141a9565b1115612df157600091505b5092915050565b8060008111612e195760405162461bcd60e51b8152600401610ab4906140d5565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663b3296422336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015612e8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eb191906141bc565b612efd5760405162461bcd60e51b815260206004820152601860248201527f466f7262696464656e3a204f6e6c792050726f746f636f6c00000000000000006044820152606401610ab4565b60035415612fbb578160026000828254612f1791906141a9565b925050819055508160086000828254612f3091906141a9565b9091555050600354612f4a670de0b6b3a764000084614144565b612f54919061415b565b60066000828254612f6591906141a9565b909155505060035460055460045460408051868152602081019490945283019190915260608201527fb2de7f58fce4830ac7100b13cdb8d26966c919277b33ed122a362543a7addf369060800160405180910390a15b5050565b6001600160a01b0382166000908152600a60205260408120805482919084908110612fec57612fec614210565b600091825260209182902060408051610120810182526008909302909101805483526001810154938301939093526002830154908201526003820154606082015260048201546080820152600582015460a0820152600682015460c082015260079091015460ff808216151560e08401819052610100928390049091161515918301919091529091508061308257508061010001515b15613091576000915050611f18565b61309a816134bd565b949350505050565b81600081116130c35760405162461bcd60e51b8152600401610ab4906140d5565b6001546001146130e55760405162461bcd60e51b8152600401610ab49061410a565b60026001556130f261341b565b33600083156131985760095460405163079b9d7760e21b81526001600160a01b0390911690631e6e75dc9061312d9085908990600401614190565b600060405180830381600087803b15801561314757600080fd5b505af115801561315b573d6000803e3d6000fd5b5050506001600160a01b038316600090815260156020526040812060058054919450889350919061318d9084906141a9565b909155506132309050565b600954604051631095e8b160e31b81526001600160a01b03909116906384af4588906131ca9085908990600401614190565b600060405180830381600087803b1580156131e457600080fd5b505af11580156131f8573d6000803e3d6000fd5b5050506001600160a01b038316600090815260146020526040812060048054919450889350919061322a9084906141a9565b90915550505b805415613243576132418285613a70565b505b600061326086836000015461325891906141a9565b866000613461565b9050816002015481613272919061417d565b6003600082825461328391906141a9565b909155505081548690839060009061329c9084906141a9565b90915550506003820180546fffffffffffffffffffffffffffffffff1916426001600160801b0316179055600282018190556132d78161349a565b600183018190558254604080519182526020820192909252861515918101919091526001600160a01b038416907fd0f836e593c496b2857b30a01b4268b1ae280ad2545285f4cadf3fe26c00763b90606001611cbf565b61333661341b565b6001546001146133585760405162461bcd60e51b8152600401610ab49061410a565b600260015561336633613bf4565b5060018055565b6133a1604051806080016040528060008152602001600081526020016000815260200160006001600160801b031681525090565b816133c3576001600160a01b03831660009081526014602052604090206133dc565b6001600160a01b03831660009081526015602052604090205b6040805160808101825282548152600183015460208201526002830154918101919091526003909101546001600160801b031660608201529392505050565b60005460ff16156113885760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610ab4565b6000821561348d57816134805760125461347b9085614144565b61309a565b60135461347b9085614144565b60115461309a9085614144565b6000670de0b6b3a7640000600654836134b39190614144565b611f18919061415b565b600080670de0b6b3a764000060065484602001516134db9190614144565b6134e5919061415b565b905082606001518110613506576060830151613501908261417d565b613509565b60005b9392505050565b336000805b84518110156136ef57600085828151811061353257613532614210565b602002602001015190506000600a6000866001600160a01b03166001600160a01b03168152602001908152602001600020828154811061357457613574614210565b9060005260206000209060080201905085156135df57600781015460ff16156135df5760405162461bcd60e51b815260206004820181905260248201527f5374616b652068617320616c7265616479206265656e2077697468647261776e6044820152606401610ab4565b6007810154610100900460ff16156136395760405162461bcd60e51b815260206004820152601860248201527f5374616b6520686173206265656e2063616e63656c6c656400000000000000006044820152606401610ab4565b604080516101208101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460ff808216151560e084015261010091829004161515908201526000906136b1906134bd565b9050808260030160008282546136c791906141a9565b909155506136d7905081866141a9565b945050505080806136e790614226565b915050613515565b508060026000828254613702919061417d565b90915550506001600160a01b0382166000908152600c60205260408120805483929061372f9084906141a9565b9091555050801561379f576009546040516301e2206160e11b81526001600160a01b03909116906303c440c29061376c9085908590600401614190565b600060405180830381600087803b15801561378657600080fd5b505af115801561379a573d6000803e3d6000fd5b505050505b816001600160a01b03167f94dcc76e9211fa75425c6978d70f34a2182dee339d4aa4f9d0a0351f62c769e382866040516137da929190614292565b60405180910390a250505050565b6137f0613db3565b6000805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6001600160a01b0382166000908152600b60205260408120805490915b81811015613908578383828154811061387257613872614210565b9060005260206000200154036138f6578261388e60018461417d565b8154811061389e5761389e614210565b90600052602060002001548382815481106138bb576138bb614210565b9060005260206000200181905550828054806138d9576138d96142ab565b600190038181906000526020600020016000905590555050505050565b8061390081614226565b915050613857565b5050505050565b6000670de0b6b3a7640000600754836134b39190614144565b6000806201518083608001514261393f919061417d565b613949919061415b565b9050600062015180600d60010154613961919061415b565b905080821015613975575060009392505050565b8360400151846080015161398991906141a9565b4211156139a6576201518084604001516139a3919061415b565b91505b600f546139b3828461417d565b60a086015186516139c4919061417d565b6139ce9190614144565b6139d8919061415b565b8460a0015161309a91906141a9565b6139ef61341b565b6000805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861381d3390565b6000670de0b6b3a76400006006548360400151613a419190614144565b613a4b919061415b565b90508160200151811015613a6157506000919050565b6020820151611f18908261417d565b60008082613a95576001600160a01b0384166000908152601460205260409020613aae565b6001600160a01b03841660009081526015602052604090205b60408051608081018252825481526001830154602082015260028301549181019190915260038201546001600160801b03166060820152909150613af190613a24565b915081600003613b05576000915050611f18565b6009546040516301e2206160e11b81526001600160a01b03909116906303c440c290613b379087908690600401614190565b600060405180830381600087803b158015613b5157600080fd5b505af1158015613b65573d6000803e3d6000fd5b50505050613b76816002015461349a565b60018201556001600160a01b0384166000908152600c602052604081208054849290613ba39084906141a9565b90915550506040805183815284151560208201526001600160a01b038616917feafb3ef7cb9229547fa473df9e43073744d337e19e2e548fa289a2747abeddc7910160405180910390a25092915050565b6001600160a01b03811660009081526015602090815260408083206014835281842082516080810184528254815260018301549481019490945260028201549284019290925260038101546001600160801b0316606084015291613c5790613a24565b60408051608081018252835481526001840154602082015260028401549181019190915260038301546001600160801b03166060820152909350613c9a90613a24565b613ca490846141a9565b925082600003613cb8575060009392505050565b6009546040516301e2206160e11b81526001600160a01b03909116906303c440c290613cea9087908790600401614190565b600060405180830381600087803b158015613d0457600080fd5b505af1158015613d18573d6000803e3d6000fd5b50505050613d29826002015461349a565b60018301556002810154613d3c9061349a565b60018201556001600160a01b0384166000908152600c602052604081208054859290613d699084906141a9565b90915550506040518381526001600160a01b038516907f39f1bc8a3004d8c2a2e71c312c419cafba6747f8552f82ba2c5fb5cc92d263189060200160405180910390a25050919050565b60005460ff166113885760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610ab4565b604051806101200160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000151581526020016000151581525090565b60405180608001604052806004906020820280368337509192915050565b6001600160a01b0381168114613e7f57600080fd5b50565b600060208284031215613e9457600080fd5b813561350981613e6a565b600081518084526020808501945080840160005b83811015613ecf57815187529582019590820190600101613eb3565b509495945050505050565b602081526000611f156020830184613e9f565b60008060408385031215613f0057600080fd5b50508035926020909101359150565b60008060008060808587031215613f2557600080fd5b5050823594602084013594506040840135936060013592509050565b600060208284031215613f5357600080fd5b5035919050565b60008083601f840112613f6c57600080fd5b50813567ffffffffffffffff811115613f8457600080fd5b6020830191508360208260051b8501011115613f9f57600080fd5b9250929050565b60008060208385031215613fb957600080fd5b823567ffffffffffffffff811115613fd057600080fd5b613fdc85828601613f5a565b90969095509350505050565b60008060408385031215613ffb57600080fd5b823561400681613e6a565b946020939093013593505050565b8015158114613e7f57600080fd5b6000806040838503121561403557600080fd5b823561404081613e6a565b9150602083013561405081614014565b809150509250929050565b60008060006040848603121561407057600080fd5b833561407b81613e6a565b9250602084013567ffffffffffffffff81111561409757600080fd5b6140a386828701613f5a565b9497909650939450505050565b600080604083850312156140c357600080fd5b82359150602083013561405081614014565b6020808252818101527f616d6f756e74206d7573742062652067726561746572207468616e207a65726f604082015260600190565b6020808252600a90820152695245454e5452414e435960b01b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417611f1857611f1861412e565b60008261417857634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115611f1857611f1861412e565b6001600160a01b03929092168252602082015260400190565b80820180821115611f1857611f1861412e565b6000602082840312156141ce57600080fd5b815161350981614014565b6020808252601a908201527f466f7262696464656e3a204f6e6c7920476f7665726e616e6365000000000000604082015260600190565b634e487b7160e01b600052603260045260246000fd5b6000600182016142385761423861412e565b5060010190565b86815260a060208201819052810185905260006001600160fb1b0386111561426657600080fd5b8560051b808860c0850137604083019590955250606081019290925260808201520160c0019392505050565b82815260406020820152600061309a6040830184613e9f565b634e487b7160e01b600052603160045260246000fdfea26469706673582212209db504b7d6c99067ebeb7f431e241e251bb0af51bbc6b0ab5b2163104376fe7064736f6c634300081300330000000000000000000000008cca793d0ec8c61f156cd4738455ab682554f4180000000000000000000000009ad41cd4f7434d33c30062301a303a9b42111d45

Deployed Bytecode

0x60806040526004361061026b5760003560e01c80637cb2b79c11610144578063b9e8346d116100b6578063ef5d9ae81161007a578063ef5d9ae81461091a578063ef78d4fd14610947578063f0fc6bca1461098a578063f520c87f1461099f578063f79d032d146109b5578063fe9b050e146109cb576102a8565b8063b9e8346d14610850578063c3d9c4b414610884578063dba41cbf146108a4578063e4aff9c4146108c4578063e982a482146108fa576102a8565b806396c82e571161010857806396c82e571461076f5780639def0543146107855780639ebea88c146107a5578063a9c26186146107c5578063ae03119314610810578063b1945e5a14610830576102a8565b80637cb2b79c146106e55780638456cb5914610705578063860015191461071a578063947a56cd14610730578063961072021461074f576102a8565b8063581b593e116101dd578063613ce410116101a1578063613ce410146105a25780636230b83d146105d45780636cc0bd24146105ea5780636dfa8d991461060a5780637b103999146106205780637be25ba214610654576102a8565b8063581b593e14610463578063584b62a1146104d75780635ab08f001461053f5780635c975abb1461055f57806360d3bdfe14610582576102a8565b80632a709b141161022f5780632a709b14146103965780632ef73e88146103ce578063374756f5146103ee5780633f4ba83a1461040e57806340e58ee5146104235780634178ec2814610443576102a8565b80630210290f146102da5780631df0af3f1461031057806324d17fa11461033257806327f00c251461035257806329f0db2214610376576102a8565b366102a85760405134815233907f5d8bc849764969eb1bcc6d0a2f55999d0167c1ccec240a4f39cf664ca9c4148e906020015b60405180910390a2005b60405134815233907f5d8bc849764969eb1bcc6d0a2f55999d0167c1ccec240a4f39cf664ca9c4148e9060200161029e565b3480156102e657600080fd5b506102fa6102f5366004613e82565b610a27565b6040516103079190613eda565b60405180910390f35b34801561031c57600080fd5b5061033061032b366004613eed565b610a93565b005b34801561033e57600080fd5b5061033061034d366004613f0f565b610e48565b34801561035e57600080fd5b5061036860055481565b604051908152602001610307565b34801561038257600080fd5b50610330610391366004613f41565b610ff4565b3480156103a257600080fd5b506009546103b6906001600160a01b031681565b6040516001600160a01b039091168152602001610307565b3480156103da57600080fd5b506103686103e9366004613e82565b6110e3565b3480156103fa57600080fd5b50610330610409366004613fa6565b6111f2565b34801561041a57600080fd5b506103306112a5565b34801561042f57600080fd5b5061033061043e366004613f41565b61138a565b34801561044f57600080fd5b5061033061045e366004613f41565b6116d7565b34801561046f57600080fd5b506104ae61047e366004613e82565b6014602052600090815260409020805460018201546002830154600390930154919290916001600160801b031684565b604080519485526020850193909352918301526001600160801b03166060820152608001610307565b3480156104e357600080fd5b506104f76104f2366004613fe8565b611cd3565b60408051998a5260208a0198909852968801959095526060870193909352608086019190915260a085015260c0840152151560e0830152151561010082015261012001610307565b34801561054b57600080fd5b5061033061055a366004613fe8565b611d41565b34801561056b57600080fd5b5060005460ff166040519015158152602001610307565b34801561058e57600080fd5b5061036861059d366004614022565b611ed6565b3480156105ae57600080fd5b506005546004546008545b60408051938452602084019290925290820152606001610307565b3480156105e057600080fd5b5061036860075481565b3480156105f657600080fd5b5061036861060536600461405b565b611f1e565b34801561061657600080fd5b5061036860085481565b34801561062c57600080fd5b506103b67f0000000000000000000000008cca793d0ec8c61f156cd4738455ab682554f41881565b34801561066057600080fd5b5061067461066f366004613fe8565b612016565b6040516103079190600061012082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e0830151151560e0830152610100808401511515818401525092915050565b3480156106f157600080fd5b50610330610700366004613e82565b6120ce565b34801561071157600080fd5b50610330612208565b34801561072657600080fd5b5061036860025481565b34801561073c57600080fd5b506011546012546013546105b992919083565b34801561075b57600080fd5b5061036861076a366004613e82565b6122eb565b34801561077b57600080fd5b5061036860035481565b34801561079157600080fd5b506103686107a0366004613fe8565b6123b9565b3480156107b157600080fd5b506103306107c03660046140b0565b6123ea565b3480156107d157600080fd5b506104ae6107e0366004613e82565b6015602052600090815260409020805460018201546002830154600390930154919290916001600160801b031684565b34801561081c57600080fd5b5061033061082b366004613fa6565b612770565b34801561083c57600080fd5b5061036861084b366004613fe8565b612d18565b34801561085c57600080fd5b506103b67f0000000000000000000000009ad41cd4f7434d33c30062301a303a9b42111d4581565b34801561089057600080fd5b5061033061089f366004613f41565b612df8565b3480156108b057600080fd5b506103686108bf366004613fe8565b612fbf565b3480156108d057600080fd5b506103686108df366004613e82565b6001600160a01b03166000908152600a602052604090205490565b34801561090657600080fd5b506103306109153660046140b0565b6130a2565b34801561092657600080fd5b50610368610935366004613e82565b600c6020526000908152604090205481565b34801561095357600080fd5b50600d54600e54600f5460105461096a9392919084565b604080519485526020850193909352918301526060820152608001610307565b34801561099657600080fd5b5061033061332e565b3480156109ab57600080fd5b5061036860065481565b3480156109c157600080fd5b5061036860045481565b3480156109d757600080fd5b506109eb6109e6366004614022565b61336d565b60405161030791908151815260208083015190820152604080830151908201526060918201516001600160801b03169181019190915260800190565b6001600160a01b0381166000908152600b6020908152604091829020805483518184028101840190945280845260609392830182828015610a8757602002820191906000526020600020905b815481526020019060010190808311610a73575b50505050509050919050565b8160008111610abd5760405162461bcd60e51b8152600401610ab4906140d5565b60405180910390fd5b600154600114610adf5760405162461bcd60e51b8152600401610ab49061410a565b6002600155610aec61341b565b6000610afb8362015180614144565b600e549091508110801590610b125750600d548311155b610b5e5760405162461bcd60e51b815260206004820152601a60248201527f6475726174696f6e206d75737420626520696e20706572696f640000000000006044820152606401610ab4565b336000610b6d86600180613461565b90506000610b7a8261349a565b6010549091504290600090670de0b6b3a764000090610b99908b614144565b610ba3919061415b565b600f54909150600090610bb6838c61417d565b610bc0919061415b565b60095460405163079b9d7760e21b81529192506001600160a01b031690631e6e75dc90610bf39089908e90600401614190565b600060405180830381600087803b158015610c0d57600080fd5b505af1158015610c21573d6000803e3d6000fd5b505050508460036000828254610c3791906141a9565b925050819055508960056000828254610c5091906141a9565b92505081905550600a6000876001600160a01b03166001600160a01b031681526020019081526020016000206040518061012001604052808c8152602001878152602001898152602001868152602001858152602001848152602001838152602001600015158152602001600015158152509080600181540180825580915050600190039060005260206000209060080201600090919091909150600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e08201518160070160006101000a81548160ff0219169083151502179055506101008201518160070160016101000a81548160ff021916908315150217905550505060006001600a6000336001600160a01b03166001600160a01b0316815260200190815260200160002080549050610dab919061417d565b336000908152600b602090815260408220805460018101825590835291200181905590506040805182815260208101869052908101899052606081018c905260808101869052600160a0820181905260c08201526001600160a01b038816907feb7bdad6029ad027c77906ce1960c5ac2111bf37b5a7bb7b63068aa4f25256179060e00160405180910390a2505060018055505050505050505050565b6001600160a01b037f0000000000000000000000008cca793d0ec8c61f156cd4738455ab682554f41816637d075595336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610ebc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee091906141bc565b610efc5760405162461bcd60e51b8152600401610ab4906141d9565b82841015610f725760405162461bcd60e51b815260206004820152603a60248201527f4475726174696f6e206d7573742062652067726561746572207468616e206f7260448201527f20657175616c20746f206d696e696d756d206475726174696f6e0000000000006064820152608401610ab4565b83821115610fe05760405162461bcd60e51b815260206004820152603560248201527f436c61696d206475726174696f6e206d757374206265206c657373207468616e6044820152741037b91032b8bab0b6103a3790323ab930ba34b7b760591b6064820152608401610ab4565b600d93909355600e91909155600f55601055565b6001600160a01b037f0000000000000000000000008cca793d0ec8c61f156cd4738455ab682554f41816637d075595336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015611068573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061108c91906141bc565b6110a85760405162461bcd60e51b8152600401610ab4906141d9565b60078190556040518181527fc6723167dfc6a0204d07a4d7c81104295b948a8fac5769b1576c202032cf8ef39060200160405180910390a150565b6000806110ef83610a27565b905060005b81518110156111eb576001600160a01b0384166000908152600a60205260408120835184908490811061112957611129614210565b60200260200101518154811061114157611141614210565b600091825260209182902060408051610120810182526008909302909101805483526001810154938301939093526002830154908201526003820154606082015260048201546080820152600582015460a0820152600682015460c082015260079091015460ff808216151560e0840152610100918290041615159082015290506111cb816134bd565b6111d590856141a9565b93505080806111e390614226565b9150506110f4565b5050919050565b6111fa61341b565b60015460011461121c5760405162461bcd60e51b8152600401610ab49061410a565b60026001558061125e5760405162461bcd60e51b815260206004820152600d60248201526c656d70747920696e646578657360981b6044820152606401610ab4565b61129d82828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525060019250613510915050565b505060018055565b6001600160a01b037f0000000000000000000000008cca793d0ec8c61f156cd4738455ab682554f4181663784cbca2336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015611319573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061133d91906141bc565b6113805760405162461bcd60e51b8152602060048201526014602482015273466f7262696464656e3a204f6e6c79205465616d60601b6044820152606401610ab4565b6113886137e8565b565b33611393613dfc565b61139d8284612016565b90508060e00151156113e75760405162461bcd60e51b815260206004820152601360248201527239ba30b5b2903430b9903bb4ba34323930bbb760691b6044820152606401610ab4565b806101000151156114305760405162461bcd60e51b81526020600482015260136024820152721cdd185ad9481a185cc818d85b98d95b1b1959606a1b6044820152606401610ab4565b61143a828461383a565b805160006114478261390f565b90506000611455828461417d565b90508260056000828254611469919061417d565b909155505060208401516003805460009061148590849061417d565b9091555060009050611496856134bd565b90508015611526576003546114b3670de0b6b3a764000083614144565b6114bd919061415b565b600660008282546114ce91906141a9565b90915550506001600160a01b0386166000908152600a6020526040902080548291908990811061150057611500614210565b9060005260206000209060080201600301600082825461152091906141a9565b90915550505b6001600160a01b0386166000908152600a602052604090208054600191908990811061155457611554614210565b6000918252602080832060076008909302019190910180549315156101000261ff0019909416939093179092556001600160a01b0388168152600a909152604081208054899081106115a8576115a8614210565b600091825260209091206008909102015560095460405163d3e96ed360e01b81526001600160a01b039091169063d3e96ed3906115eb9089908690600401614190565b600060405180830381600087803b15801561160557600080fd5b505af1158015611619573d6000803e3d6000fd5b50506009546040516376555fed60e11b8152600481018790526001600160a01b03909116925063ecaabfda9150602401600060405180830381600087803b15801561166357600080fd5b505af1158015611677573d6000803e3d6000fd5b505060408051428152602081018b9052908101869052606081018590526001600160a01b03891692507f10de281942f9db9a7f40110d5f1d818f2ab6f7e182a6d5c0727c6804c17b84bf915060800160405180910390a250505050505050565b6116df61341b565b6001546001146117015760405162461bcd60e51b8152600401610ab49061410a565b6002600155336000818152600a6020526040812080548490811061172757611727614210565b906000526020600020906008020190508060020154816004015461174b91906141a9565b42101561179a5760405162461bcd60e51b815260206004820181905260248201527f596f752063616e277420776974686472617720746865207374616b65207965746044820152606401610ab4565b600781015460ff16156117e35760405162461bcd60e51b815260206004820152601160248201527030b63932b0b23c903bb4ba34323930bbb760791b6044820152606401610ab4565b6007810154610100900460ff161561182f5760405162461bcd60e51b815260206004820152600f60248201526e1cdd185ad94818d85b98d95b1b1959608a1b6044820152606401610ab4565b604080516101208101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460ff808216151560e084015261010091829004161515908201526000906118a790613928565b604080516101208101825284548152600185015460208201526002850154918101919091526003840154606082015260048401546080820152600584015460a0820152600684015460c0820152600784015460ff808216151560e08401526101009182900416151590820152909150600090611922906134bd565b9050811561198f5760095460405163e24acd4b60e01b81526001600160a01b039091169063e24acd4b9061195c9087908690600401614190565b600060405180830381600087803b15801561197657600080fd5b505af115801561198a573d6000803e3d6000fd5b505050505b825460009061199f90849061417d565b90508015611a6a57600954604051633802f5af60e11b81526001600160a01b0390911690637005eb5e906119d99083908590600401614190565b600060405180830381600087803b1580156119f357600080fd5b505af1158015611a07573d6000803e3d6000fd5b505060095460405163673b31a760e01b8152600481018590526001600160a01b03909116925063673b31a79150602401600060405180830381600087803b158015611a5157600080fd5b505af1158015611a65573d6000803e3d6000fd5b505050505b60095484546040516376555fed60e11b81526001600160a01b039092169163ecaabfda91611a9e9160040190815260200190565b600060405180830381600087803b158015611ab857600080fd5b505af1158015611acc573d6000803e3d6000fd5b505050506000821115611c19576009546040516301e2206160e11b81526001600160a01b03909116906303c440c290611b0b9088908690600401614190565b600060405180830381600087803b158015611b2557600080fd5b505af1158015611b39573d6000803e3d6000fd5b5050506001600160a01b0386166000908152600a60205260409020805484925088908110611b6957611b69614210565b90600052602060002090600802016003016000828254611b8991906141a9565b925050819055508160026000828254611ba2919061417d565b90915550506001600160a01b0385166000908152600c602052604081208054849290611bcf9084906141a9565b909155505060408051838152602081018890526001600160a01b038716917f93b2b5baeb90867d00d09e02023eed58ae019d05b1c254578512984cc85e5ba6910160405180910390a25b60078401805460ff19166001179055611c32858761383a565b836001015460036000828254611c48919061417d565b9091555050835460058054600090611c6190849061417d565b90915550506001840154845460408051428152602081018a9052908101839052606081019290925260808201526001600160a01b038616907fb7ee00edafdb5db3a1b52a5789a6b562eb48268842d113dbfe860b6f86e5f5959060a0015b60405180910390a250506001805550505050565b600a6020528160005260406000208181548110611cef57600080fd5b6000918252602090912060089091020180546001820154600283015460038401546004850154600586015460068701546007909701549598509396509194909391929160ff8082169161010090041689565b6001600160a01b037f0000000000000000000000008cca793d0ec8c61f156cd4738455ab682554f41816637d075595336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015611db5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dd991906141bc565b611df55760405162461bcd60e51b8152600401610ab4906141d9565b80471015611e3c5760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b6044820152606401610ab4565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611e89576040519150601f19603f3d011682016040523d82523d6000602084013e611e8e565b606091505b5050905080611ed15760405162461bcd60e51b815260206004820152600f60248201526e15da5d1a191c985dc819985a5b1959608a1b6044820152606401610ab4565b505050565b600081611efb576001600160a01b038316600090815260146020526040902054611f15565b6001600160a01b0383166000908152601560205260409020545b90505b92915050565b6000805b8281101561200e576001600160a01b0385166000908152600a60205260408120858584818110611f5457611f54614210565b9050602002013581548110611f6b57611f6b614210565b60009182526020918290206040805161012081018252600890930290910180548084526001820154948401949094526002810154918301919091526003810154606083015260048101546080830152600581015460a0830152600681015460c08301526007015460ff808216151560e084015261010091829004161515908201529150611ff890846141a9565b925050808061200690614226565b915050611f22565b509392505050565b61201e613dfc565b6001600160a01b0383166000908152600a6020526040902080548390811061204857612048614210565b600091825260209182902060408051610120810182526008909302909101805483526001810154938301939093526002830154908201526003820154606082015260048201546080820152600582015460a0820152600682015460c082015260079091015460ff808216151560e084015261010091829004161515908201529392505050565b6001600160a01b037f0000000000000000000000008cca793d0ec8c61f156cd4738455ab682554f41816637d075595336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015612142573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061216691906141bc565b6121825760405162461bcd60e51b8152600401610ab4906141d9565b6001600160a01b0381166121e65760405162461bcd60e51b815260206004820152602560248201527f746f6b656e206d616e6167657220616464726573732063616e206e6f74206265604482015264207a65726f60d81b6064820152608401610ab4565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b037f0000000000000000000000008cca793d0ec8c61f156cd4738455ab682554f4181663784cbca2336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa15801561227c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122a091906141bc565b6122e35760405162461bcd60e51b8152602060048201526014602482015273466f7262696464656e3a204f6e6c79205465616d60601b6044820152606401610ab4565b6113886139e7565b6001600160a01b0381166000908152601560209081526040808320815160808101835281548152600182015493810193909352600281015491830191909152600301546001600160801b0316606082015261234590613a24565b61234f90826141a9565b6001600160a01b0383166000908152601460209081526040918290208251608081018452815481526001820154928101929092526002810154928201929092526003909101546001600160801b031660608201529091506123af90613a24565b611f1890826141a9565b600b60205281600052604060002081815481106123d557600080fd5b90600052602060002001600091509150505481565b60015460011461240c5760405162461bcd60e51b8152600401610ab49061410a565b600260015561241961341b565b3360008261243e576001600160a01b0382166000908152601460205260409020612457565b6001600160a01b03821660009081526015602052604090205b905083816000015410156124ad5760405162461bcd60e51b815260206004820152601960248201527f496e73756666696369656e74207374616b6520616d6f756e74000000000000006044820152606401610ab4565b6009546001600160a01b031660006124c48661390f565b905060006124d2828861417d565b905060006124e08688613a70565b5086156125ce576040516376555fed60e11b8152600481018490526001600160a01b0385169063ecaabfda90602401600060405180830381600087803b15801561252957600080fd5b505af115801561253d573d6000803e3d6000fd5b505060405163d3e96ed360e01b81526001600160a01b038716925063d3e96ed3915061256f9089908690600401614190565b600060405180830381600087803b15801561258957600080fd5b505af115801561259d573d6000803e3d6000fd5b50506012546125af9250905089614144565b905087600560008282546125c3919061417d565b909155506126b09050565b60405163673b31a760e01b8152600481018490526001600160a01b0385169063673b31a790602401600060405180830381600087803b15801561261057600080fd5b505af1158015612624573d6000803e3d6000fd5b505060405163562084bd60e11b81526001600160a01b038716925063ac41097a91506126569089908690600401614190565b600060405180830381600087803b15801561267057600080fd5b505af1158015612684573d6000803e3d6000fd5b50506011546126969250905089614144565b905087600460008282546126aa919061417d565b90915550505b80600360008282546126c2919061417d565b90915550508454889086906000906126db90849061417d565b92505081905550808560020160008282546126f6919061417d565b909155505060028501546127099061349a565b6001860155604080514281526020810184905290810184905287151560608201526001600160a01b038716907fc7ccdcb2d25f572c6814e377dbb34ea4318a4b7d3cd890f5cfad699d75327c7c9060800160405180910390a2505060018055505050505050565b61277861341b565b60015460011461279a5760405162461bcd60e51b8152600401610ab49061410a565b6002600155336127a8613e4c565b60005b83811015612a7d5760008585838181106127c7576127c7614210565b9050602002013590506000600a6000866001600160a01b03166001600160a01b03168152602001908152602001600020828154811061280857612808614210565b906000526020600020906008020190508060020154816004015461282c91906141a9565b42101561287b5760405162461bcd60e51b815260206004820181905260248201527f596f752063616e277420776974686472617720746865207374616b65207965746044820152606401610ab4565b600781015460ff16156128c45760405162461bcd60e51b815260206004820152601160248201527030b63932b0b23c903bb4ba34323930bbb760791b6044820152606401610ab4565b6007810154610100900460ff16156129105760405162461bcd60e51b815260206004820152600f60248201526e1cdd185ad94818d85b98d95b1b1959608a1b6044820152606401610ab4565b6001810154845185906129249083906141a9565b905250604080516101208101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460ff808216151560e0840152610100918290041615159082015261299c90613928565b6020850180516129ad9083906141a9565b905250604080516101208101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460ff808216151560e08401526101009182900416151590820152612a25906134bd565b604085018051612a369083906141a9565b9052508054606085018051612a4c9083906141a9565b90525060078101805460ff19166001179055612a68858361383a565b50508080612a7590614226565b9150506127ab565b50602081015115612af157600954602082015160405163e24acd4b60e01b81526001600160a01b039092169163e24acd4b91612abe91869190600401614190565b600060405180830381600087803b158015612ad857600080fd5b505af1158015612aec573d6000803e3d6000fd5b505050505b60208101516060820151600091612b079161417d565b90508015612bd257600954604051633802f5af60e11b81526001600160a01b0390911690637005eb5e90612b419083908590600401614190565b600060405180830381600087803b158015612b5b57600080fd5b505af1158015612b6f573d6000803e3d6000fd5b505060095460405163673b31a760e01b8152600481018590526001600160a01b03909116925063673b31a79150602401600060405180830381600087803b158015612bb957600080fd5b505af1158015612bcd573d6000803e3d6000fd5b505050505b60095460608301516040516376555fed60e11b815260048101919091526001600160a01b039091169063ecaabfda90602401600060405180830381600087803b158015612c1e57600080fd5b505af1158015612c32573d6000803e3d6000fd5b5050505081600060048110612c4957612c49614210565b602002015160036000828254612c5f919061417d565b9091555050606082015160058054600090612c7b90849061417d565b90915550506040805160208087028281018201909352868252612cb99288918891829185019084908082843760009201829052509250613510915050565b602082015160608301516040516001600160a01b038616927f670058fd657dd0cbca748af3a687a4d5b441b61753a2ccbea58894eac13d559992612d059242928b928b9282919061423f565b60405180910390a2505060018055505050565b6001600160a01b0382166000908152600a60205260408120805482919084908110612d4557612d45614210565b600091825260209182902060408051610120810182526008909302909101805483526001810154938301939093526002830154908201526003820154606082015260048201546080820152600582015460a0820152600682015460c082015260079091015460ff808216151560e084015261010091829004161515908201529050612dcf81613928565b91504281604001518260800151612de691906141a9565b1115612df157600091505b5092915050565b8060008111612e195760405162461bcd60e51b8152600401610ab4906140d5565b6001600160a01b037f0000000000000000000000008cca793d0ec8c61f156cd4738455ab682554f4181663b3296422336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015612e8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eb191906141bc565b612efd5760405162461bcd60e51b815260206004820152601860248201527f466f7262696464656e3a204f6e6c792050726f746f636f6c00000000000000006044820152606401610ab4565b60035415612fbb578160026000828254612f1791906141a9565b925050819055508160086000828254612f3091906141a9565b9091555050600354612f4a670de0b6b3a764000084614144565b612f54919061415b565b60066000828254612f6591906141a9565b909155505060035460055460045460408051868152602081019490945283019190915260608201527fb2de7f58fce4830ac7100b13cdb8d26966c919277b33ed122a362543a7addf369060800160405180910390a15b5050565b6001600160a01b0382166000908152600a60205260408120805482919084908110612fec57612fec614210565b600091825260209182902060408051610120810182526008909302909101805483526001810154938301939093526002830154908201526003820154606082015260048201546080820152600582015460a0820152600682015460c082015260079091015460ff808216151560e08401819052610100928390049091161515918301919091529091508061308257508061010001515b15613091576000915050611f18565b61309a816134bd565b949350505050565b81600081116130c35760405162461bcd60e51b8152600401610ab4906140d5565b6001546001146130e55760405162461bcd60e51b8152600401610ab49061410a565b60026001556130f261341b565b33600083156131985760095460405163079b9d7760e21b81526001600160a01b0390911690631e6e75dc9061312d9085908990600401614190565b600060405180830381600087803b15801561314757600080fd5b505af115801561315b573d6000803e3d6000fd5b5050506001600160a01b038316600090815260156020526040812060058054919450889350919061318d9084906141a9565b909155506132309050565b600954604051631095e8b160e31b81526001600160a01b03909116906384af4588906131ca9085908990600401614190565b600060405180830381600087803b1580156131e457600080fd5b505af11580156131f8573d6000803e3d6000fd5b5050506001600160a01b038316600090815260146020526040812060048054919450889350919061322a9084906141a9565b90915550505b805415613243576132418285613a70565b505b600061326086836000015461325891906141a9565b866000613461565b9050816002015481613272919061417d565b6003600082825461328391906141a9565b909155505081548690839060009061329c9084906141a9565b90915550506003820180546fffffffffffffffffffffffffffffffff1916426001600160801b0316179055600282018190556132d78161349a565b600183018190558254604080519182526020820192909252861515918101919091526001600160a01b038416907fd0f836e593c496b2857b30a01b4268b1ae280ad2545285f4cadf3fe26c00763b90606001611cbf565b61333661341b565b6001546001146133585760405162461bcd60e51b8152600401610ab49061410a565b600260015561336633613bf4565b5060018055565b6133a1604051806080016040528060008152602001600081526020016000815260200160006001600160801b031681525090565b816133c3576001600160a01b03831660009081526014602052604090206133dc565b6001600160a01b03831660009081526015602052604090205b6040805160808101825282548152600183015460208201526002830154918101919091526003909101546001600160801b031660608201529392505050565b60005460ff16156113885760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610ab4565b6000821561348d57816134805760125461347b9085614144565b61309a565b60135461347b9085614144565b60115461309a9085614144565b6000670de0b6b3a7640000600654836134b39190614144565b611f18919061415b565b600080670de0b6b3a764000060065484602001516134db9190614144565b6134e5919061415b565b905082606001518110613506576060830151613501908261417d565b613509565b60005b9392505050565b336000805b84518110156136ef57600085828151811061353257613532614210565b602002602001015190506000600a6000866001600160a01b03166001600160a01b03168152602001908152602001600020828154811061357457613574614210565b9060005260206000209060080201905085156135df57600781015460ff16156135df5760405162461bcd60e51b815260206004820181905260248201527f5374616b652068617320616c7265616479206265656e2077697468647261776e6044820152606401610ab4565b6007810154610100900460ff16156136395760405162461bcd60e51b815260206004820152601860248201527f5374616b6520686173206265656e2063616e63656c6c656400000000000000006044820152606401610ab4565b604080516101208101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460ff808216151560e084015261010091829004161515908201526000906136b1906134bd565b9050808260030160008282546136c791906141a9565b909155506136d7905081866141a9565b945050505080806136e790614226565b915050613515565b508060026000828254613702919061417d565b90915550506001600160a01b0382166000908152600c60205260408120805483929061372f9084906141a9565b9091555050801561379f576009546040516301e2206160e11b81526001600160a01b03909116906303c440c29061376c9085908590600401614190565b600060405180830381600087803b15801561378657600080fd5b505af115801561379a573d6000803e3d6000fd5b505050505b816001600160a01b03167f94dcc76e9211fa75425c6978d70f34a2182dee339d4aa4f9d0a0351f62c769e382866040516137da929190614292565b60405180910390a250505050565b6137f0613db3565b6000805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6001600160a01b0382166000908152600b60205260408120805490915b81811015613908578383828154811061387257613872614210565b9060005260206000200154036138f6578261388e60018461417d565b8154811061389e5761389e614210565b90600052602060002001548382815481106138bb576138bb614210565b9060005260206000200181905550828054806138d9576138d96142ab565b600190038181906000526020600020016000905590555050505050565b8061390081614226565b915050613857565b5050505050565b6000670de0b6b3a7640000600754836134b39190614144565b6000806201518083608001514261393f919061417d565b613949919061415b565b9050600062015180600d60010154613961919061415b565b905080821015613975575060009392505050565b8360400151846080015161398991906141a9565b4211156139a6576201518084604001516139a3919061415b565b91505b600f546139b3828461417d565b60a086015186516139c4919061417d565b6139ce9190614144565b6139d8919061415b565b8460a0015161309a91906141a9565b6139ef61341b565b6000805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861381d3390565b6000670de0b6b3a76400006006548360400151613a419190614144565b613a4b919061415b565b90508160200151811015613a6157506000919050565b6020820151611f18908261417d565b60008082613a95576001600160a01b0384166000908152601460205260409020613aae565b6001600160a01b03841660009081526015602052604090205b60408051608081018252825481526001830154602082015260028301549181019190915260038201546001600160801b03166060820152909150613af190613a24565b915081600003613b05576000915050611f18565b6009546040516301e2206160e11b81526001600160a01b03909116906303c440c290613b379087908690600401614190565b600060405180830381600087803b158015613b5157600080fd5b505af1158015613b65573d6000803e3d6000fd5b50505050613b76816002015461349a565b60018201556001600160a01b0384166000908152600c602052604081208054849290613ba39084906141a9565b90915550506040805183815284151560208201526001600160a01b038616917feafb3ef7cb9229547fa473df9e43073744d337e19e2e548fa289a2747abeddc7910160405180910390a25092915050565b6001600160a01b03811660009081526015602090815260408083206014835281842082516080810184528254815260018301549481019490945260028201549284019290925260038101546001600160801b0316606084015291613c5790613a24565b60408051608081018252835481526001840154602082015260028401549181019190915260038301546001600160801b03166060820152909350613c9a90613a24565b613ca490846141a9565b925082600003613cb8575060009392505050565b6009546040516301e2206160e11b81526001600160a01b03909116906303c440c290613cea9087908790600401614190565b600060405180830381600087803b158015613d0457600080fd5b505af1158015613d18573d6000803e3d6000fd5b50505050613d29826002015461349a565b60018301556002810154613d3c9061349a565b60018201556001600160a01b0384166000908152600c602052604081208054859290613d699084906141a9565b90915550506040518381526001600160a01b038516907f39f1bc8a3004d8c2a2e71c312c419cafba6747f8552f82ba2c5fb5cc92d263189060200160405180910390a25050919050565b60005460ff166113885760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610ab4565b604051806101200160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000151581526020016000151581525090565b60405180608001604052806004906020820280368337509192915050565b6001600160a01b0381168114613e7f57600080fd5b50565b600060208284031215613e9457600080fd5b813561350981613e6a565b600081518084526020808501945080840160005b83811015613ecf57815187529582019590820190600101613eb3565b509495945050505050565b602081526000611f156020830184613e9f565b60008060408385031215613f0057600080fd5b50508035926020909101359150565b60008060008060808587031215613f2557600080fd5b5050823594602084013594506040840135936060013592509050565b600060208284031215613f5357600080fd5b5035919050565b60008083601f840112613f6c57600080fd5b50813567ffffffffffffffff811115613f8457600080fd5b6020830191508360208260051b8501011115613f9f57600080fd5b9250929050565b60008060208385031215613fb957600080fd5b823567ffffffffffffffff811115613fd057600080fd5b613fdc85828601613f5a565b90969095509350505050565b60008060408385031215613ffb57600080fd5b823561400681613e6a565b946020939093013593505050565b8015158114613e7f57600080fd5b6000806040838503121561403557600080fd5b823561404081613e6a565b9150602083013561405081614014565b809150509250929050565b60008060006040848603121561407057600080fd5b833561407b81613e6a565b9250602084013567ffffffffffffffff81111561409757600080fd5b6140a386828701613f5a565b9497909650939450505050565b600080604083850312156140c357600080fd5b82359150602083013561405081614014565b6020808252818101527f616d6f756e74206d7573742062652067726561746572207468616e207a65726f604082015260600190565b6020808252600a90820152695245454e5452414e435960b01b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417611f1857611f1861412e565b60008261417857634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115611f1857611f1861412e565b6001600160a01b03929092168252602082015260400190565b80820180821115611f1857611f1861412e565b6000602082840312156141ce57600080fd5b815161350981614014565b6020808252601a908201527f466f7262696464656e3a204f6e6c7920476f7665726e616e6365000000000000604082015260600190565b634e487b7160e01b600052603260045260246000fd5b6000600182016142385761423861412e565b5060010190565b86815260a060208201819052810185905260006001600160fb1b0386111561426657600080fd5b8560051b808860c0850137604083019590955250606081019290925260808201520160c0019392505050565b82815260406020820152600061309a6040830184613e9f565b634e487b7160e01b600052603160045260246000fdfea26469706673582212209db504b7d6c99067ebeb7f431e241e251bb0af51bbc6b0ab5b2163104376fe7064736f6c63430008130033

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

0000000000000000000000008cca793d0ec8c61f156cd4738455ab682554f4180000000000000000000000009ad41cd4f7434d33c30062301a303a9b42111d45

-----Decoded View---------------
Arg [0] : _vaultRegistry (address): 0x8Cca793D0ec8C61f156cD4738455ab682554f418
Arg [1] : _timelock (address): 0x9ad41cD4F7434D33C30062301a303A9b42111D45

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000008cca793d0ec8c61f156cd4738455ab682554f418
Arg [1] : 0000000000000000000000009ad41cd4f7434d33c30062301a303a9b42111d45


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.