Contract
0x57A1CE7686F3B2AB61F5191c76361F985b57E0fa
21
Contract Overview
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Contract Name:
SingleStakingRewards
Compiler Version
v0.8.13+commit.abaa5c0e
Contract Source Code (Solidity)
/** *Submitted for verification at snowtrace.io on 2022-04-11 */ // SPDX-License-Identifier: BUSL-1.1 // File: contracts/interfaces/IElkERC20.sol pragma solidity >=0.5.0; interface IElkERC20 { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; } // File: @openzeppelin/[email protected]/utils/Address.sol // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File: @openzeppelin/[email protected]/token/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `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); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File: @openzeppelin/[email protected]/token/ERC20/utils/SafeERC20.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // File: @openzeppelin/[email protected]/security/ReentrancyGuard.sol // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } // File: @openzeppelin/[email protected]/utils/math/Math.sol // OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a / b + (a % b == 0 ? 0 : 1); } } // File: @openzeppelin/[email protected]/utils/Context.sol // 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: @openzeppelin/[email protected]/security/Pausable.sol // OpenZeppelin Contracts v4.4.1 (security/Pausable.sol) pragma solidity ^0.8.0; /** * @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 Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { 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: @openzeppelin/c[email protected]/access/Ownable.sol // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: contracts/SingleStakingRewardsNewNew.sol pragma solidity >=0.8.0; contract SingleStakingRewards is ReentrancyGuard, Ownable, Pausable { using SafeERC20 for IERC20; /* ========== STATE VARIABLES ========== */ IERC20 public immutable rewardsToken; IERC20 public immutable stakingToken; uint256 public periodFinish; uint256 public rewardRate; uint256 public rewardsDuration; uint256 public lastUpdateTime; uint256 public rewardPerTokenStored; mapping(address => uint256) public userRewardPerTokenPaid; mapping(address => uint256) public rewards; IERC20 public boosterToken; uint256 public boosterRewardRate; uint256 public boosterRewardPerTokenStored; mapping(address => uint256) public userBoosterRewardPerTokenPaid; mapping(address => uint256) public boosterRewards; uint256[] public feeSchedule; uint256[] public withdrawalFeesPct; uint256 public withdrawalFeesUnit = 10000; // unit for fees uint256 public maxWithdrawalFee = 1000; // max withdrawal fee (here, 10%) mapping(address => uint256) public lastStakedTime; uint256 public totalFees; uint256 private _totalSupply; mapping(address => uint256) private _balances; /* ========== CONSTRUCTOR ========== */ constructor( address _rewardsToken, address _stakingToken, address _boosterToken, uint256 _rewardsDuration, uint256[] memory _feeSchedule, // assumes a sorted array uint256[] memory _withdrawalFeesPct // aligned to fee schedule ) { require(_boosterToken != _rewardsToken, "The booster token must be different from the reward token"); require(_boosterToken != _stakingToken, "The booster token must be different from the staking token"); require(_rewardsDuration > 0, "Rewards duration cannot be zero"); rewardsToken = IERC20(_rewardsToken); stakingToken = IERC20(_stakingToken); boosterToken = IERC20(_boosterToken); rewardsDuration = _rewardsDuration; _setWithdrawalFees(_feeSchedule, _withdrawalFeesPct); } /* ========== VIEWS ========== */ function totalSupply() external view returns (uint256) { return _totalSupply; } function balanceOf(address account) external view returns (uint256) { return _balances[account]; } function lastTimeRewardApplicable() public view returns (uint256) { return Math.min(block.timestamp, periodFinish); } function rewardPerToken() public view returns (uint256) { if (_totalSupply == 0) { return rewardPerTokenStored; } return rewardPerTokenStored + (lastTimeRewardApplicable() - lastUpdateTime) * rewardRate * 1e18 / _totalSupply; } function earned(address account) public view returns (uint256) { return _balances[account] * (rewardPerToken() - userRewardPerTokenPaid[account]) / 1e18 + rewards[account]; } function getRewardForDuration() external view returns (uint256) { return rewardRate * rewardsDuration; } function boosterRewardPerToken() public view returns (uint256) { if (_totalSupply == 0) { return boosterRewardPerTokenStored; } return boosterRewardPerTokenStored + (lastTimeRewardApplicable() - lastUpdateTime) * boosterRewardRate * 1e18 / _totalSupply; } function boosterEarned(address account) public view returns (uint256) { return _balances[account] * (boosterRewardPerToken() - userBoosterRewardPerTokenPaid[account]) / 1e18 + boosterRewards[account]; } function getBoosterRewardForDuration() external view returns (uint256) { return boosterRewardRate * rewardsDuration; } function exitFee(address account) external view returns (uint256) { return fee(account, _balances[account]); } function fee(address account, uint256 withdrawalAmount) public view returns (uint256) { for (uint i=0; i < feeSchedule.length; ++i) { if (block.timestamp - lastStakedTime[account] < feeSchedule[i]) { return withdrawalAmount * withdrawalFeesPct[i] / withdrawalFeesUnit; } } return 0; } /* ========== MUTATIVE FUNCTIONS ========== */ function stake(uint256 amount) external nonReentrant whenNotPaused updateReward(msg.sender) { require(amount > 0, "Cannot stake 0"); _totalSupply = _totalSupply + amount; _balances[msg.sender] = _balances[msg.sender] + amount; lastStakedTime[msg.sender] = block.timestamp; stakingToken.safeTransferFrom(msg.sender, address(this), amount); emit Staked(msg.sender, amount); } function stakeWithPermit(uint256 amount, uint deadline, uint8 v, bytes32 r, bytes32 s) external nonReentrant whenNotPaused updateReward(msg.sender) { require(amount > 0, "Cannot stake 0"); _totalSupply = _totalSupply + amount; _balances[msg.sender] = _balances[msg.sender] + amount; // permit IElkERC20(address(stakingToken)).permit(msg.sender, address(this), amount, deadline, v, r, s); lastStakedTime[msg.sender] = block.timestamp; stakingToken.safeTransferFrom(msg.sender, address(this), amount); emit Staked(msg.sender, amount); } function withdraw(uint256 amount) public nonReentrant updateReward(msg.sender) { _withdraw(amount); } function emergencyWithdraw(uint256 amount) external nonReentrant { _withdraw(amount); } function _withdraw(uint256 amount) private { require(amount > 0, "Cannot withdraw 0"); uint256 balance = _balances[msg.sender]; require(amount <= balance, "Cannot withdraw more than account balance"); _totalSupply = _totalSupply - amount; uint256 collectedFee = fee(msg.sender, amount); _balances[msg.sender] = balance - amount; uint256 withdrawableBalance = amount - collectedFee; stakingToken.safeTransfer(msg.sender, withdrawableBalance); emit Withdrawn(msg.sender, withdrawableBalance); if (collectedFee > 0) { emit FeesCollected(msg.sender, collectedFee); totalFees = totalFees + collectedFee; } } function getReward() public nonReentrant updateReward(msg.sender) { uint256 reward = rewards[msg.sender]; if (reward > 0) { rewards[msg.sender] = 0; rewardsToken.safeTransfer(msg.sender, reward); emit RewardPaid(msg.sender, reward); } } function getBoosterReward() public nonReentrant updateReward(msg.sender) { if (address(boosterToken) != address(0)) { uint256 reward = boosterRewards[msg.sender]; if (reward > 0) { boosterRewards[msg.sender] = 0; boosterToken.safeTransfer(msg.sender, reward); emit BoosterRewardPaid(msg.sender, reward); } } } function exit() external { withdraw(_balances[msg.sender]); getReward(); getBoosterReward(); } /* ========== RESTRICTED FUNCTIONS ========== */ function sendRewardsAndStartEmission(uint256 reward, uint256 boosterReward, uint256 duration) external onlyOwner { rewardsToken.safeTransferFrom(msg.sender, address(this), reward); if (address(boosterToken) != address(0) && boosterReward > 0) { boosterToken.safeTransferFrom(owner(), address(this), boosterReward); } _startEmission(reward, boosterReward, duration); } function startEmission(uint256 reward, uint256 boosterReward, uint256 duration) external onlyOwner { _startEmission(reward, boosterReward, duration); } function stopEmission() external onlyOwner { require(block.timestamp < periodFinish, "Cannot stop rewards emissions if not started or already finished"); uint256 tokensToBurn; uint256 boosterTokensToBurn; if (_totalSupply == 0) { tokensToBurn = rewardsToken.balanceOf(address(this)); if (address(boosterToken) != address(0)) { boosterTokensToBurn = boosterToken.balanceOf(address(this)); } else { boosterTokensToBurn = 0; } } else { uint256 remaining = periodFinish - block.timestamp; tokensToBurn = rewardRate * remaining; boosterTokensToBurn = boosterRewardRate * remaining; } periodFinish = block.timestamp; if (tokensToBurn > 0) { rewardsToken.safeTransfer(owner(), tokensToBurn); } if (address(boosterToken) != address(0) && boosterTokensToBurn > 0) { boosterToken.safeTransfer(owner(), boosterTokensToBurn); } emit RewardsEmissionEnded(tokensToBurn); } function recoverERC20(address tokenAddress, uint256 tokenAmount) external onlyOwner { IERC20(tokenAddress).safeTransfer(msg.sender, tokenAmount); emit Recovered(tokenAddress, tokenAmount); } function recoverLeftoverReward() external onlyOwner { require(_totalSupply == 0 && rewardsToken == stakingToken, "Cannot recover leftover reward if it is not the staking token or there are still staked tokens"); uint256 tokensToBurn = rewardsToken.balanceOf(address(this)); if (tokensToBurn > 0) { rewardsToken.safeTransfer(msg.sender, tokensToBurn); } emit LeftoverRewardRecovered(tokensToBurn); } function recoverLeftoverBooster() external onlyOwner { require(address(boosterToken) != address(0), "Cannot recover leftover booster if there was no booster token set"); require(_totalSupply == 0, "Cannot recover leftover booster if there are still staked tokens"); uint256 tokensToBurn = boosterToken.balanceOf(address(this)); if (tokensToBurn > 0) { boosterToken.safeTransfer(msg.sender, tokensToBurn); } emit LeftoverBoosterRecovered(tokensToBurn); } function recoverFees() external onlyOwner { uint256 previousFees = totalFees; totalFees = 0; stakingToken.safeTransfer(owner(), previousFees); emit FeesRecovered(previousFees); } function setRewardsDuration(uint256 duration) external onlyOwner { require( block.timestamp > periodFinish, "Previous rewards period must be complete before changing the duration for the new period" ); _setRewardsDuration(duration); } // Booster Rewards function setBoosterToken(address _boosterToken) external onlyOwner { require(_boosterToken != address(rewardsToken), "The booster token must be different from the reward token"); require(_boosterToken != address(stakingToken), "The booster token must be different from the staking token"); boosterToken = IERC20(_boosterToken); emit BoosterRewardSet(_boosterToken); } function pause() external onlyOwner { _pause(); } function unpause() external onlyOwner { _unpause(); } // Withdrawal Fees function setWithdrawalFees(uint256[] memory _feeSchedule, uint256[] memory _withdrawalFees) external onlyOwner { _setWithdrawalFees(_feeSchedule, _withdrawalFees); } // Private functions function _setRewardsDuration(uint256 duration) private { rewardsDuration = duration; emit RewardsDurationUpdated(rewardsDuration); } function _setWithdrawalFees(uint256[] memory _feeSchedule, uint256[] memory _withdrawalFeesPct) private { require(_feeSchedule.length == _withdrawalFeesPct.length, "Fee schedule and withdrawal fees arrays must be the same length!"); require(_feeSchedule.length <= 10, "Fee schedule and withdrawal fees arrays lengths cannot be larger than 10!"); uint256 lastFeeSchedule = 0; uint256 lastWithdrawalFee = maxWithdrawalFee + 1; for(uint256 i = 0; i < _feeSchedule.length; ++i) { require(_feeSchedule[i] > lastFeeSchedule, "Fee schedule must be ascending!"); require(_withdrawalFeesPct[i] < lastWithdrawalFee, "Withdrawal fees must be descending and lower than maximum!"); lastFeeSchedule = _feeSchedule[i]; lastWithdrawalFee = _withdrawalFeesPct[i]; } feeSchedule = _feeSchedule; withdrawalFeesPct = _withdrawalFeesPct; emit WithdrawalFeesSet(_feeSchedule, _withdrawalFeesPct); } // Must send reward before calling this! function _startEmission(uint256 reward, uint256 boosterReward, uint256 duration) private updateReward(address(0)) { if (duration > 0) { _setRewardsDuration(duration); } if (block.timestamp >= periodFinish) { rewardRate = reward / rewardsDuration; boosterRewardRate = boosterReward / rewardsDuration; } else { uint256 remaining = periodFinish - block.timestamp; uint256 leftover = remaining * rewardRate; rewardRate = (reward + leftover) / rewardsDuration; uint256 boosterLeftover = remaining * boosterRewardRate; boosterRewardRate = (boosterReward + boosterLeftover) / rewardsDuration; } // Ensure the provided reward amount is not more than the balance in the contract. // This keeps the reward rate in the right range, preventing overflows due to // very high values of rewardRate in the earned and rewardsPerToken functions; // Reward + leftover must be less than 2^256 / 10^18 to avoid overflow. uint balance = rewardsToken.balanceOf(address(this)); if (rewardsToken != stakingToken) { require(rewardRate <= balance / rewardsDuration, "Provided reward too high"); } else { // Handle care where rewardsToken is the same as stakingToken (need to subtract total supply) require(rewardRate <= (balance - _totalSupply) / rewardsDuration, "Provided reward too high"); } if (address(boosterToken) != address(0)) { uint boosterBalance = boosterToken.balanceOf(address(this)); require(boosterRewardRate <= boosterBalance / rewardsDuration, "Provided booster reward too high"); } lastUpdateTime = block.timestamp; periodFinish = block.timestamp + rewardsDuration; emit RewardsEmissionStarted(reward, boosterReward, duration); } /* ========== MODIFIERS ========== */ modifier updateReward(address account) { rewardPerTokenStored = rewardPerToken(); boosterRewardPerTokenStored = boosterRewardPerToken(); lastUpdateTime = lastTimeRewardApplicable(); if (account != address(0)) { rewards[account] = earned(account); userRewardPerTokenPaid[account] = rewardPerTokenStored; boosterRewards[account] = boosterEarned(account); userBoosterRewardPerTokenPaid[account] = boosterRewardPerTokenStored; } _; } /* ========== EVENTS ========== */ event Staked(address indexed user, uint256 amount); event Withdrawn(address indexed user, uint256 amount); event RewardPaid(address indexed user, uint256 reward); event BoosterRewardPaid(address indexed user, uint256 reward); event RewardsDurationUpdated(uint256 newDuration); event Recovered(address token, uint256 amount); event LeftoverRewardRecovered(uint256 amount); event LeftoverBoosterRecovered(uint256 amount); event RewardsEmissionStarted(uint256 reward, uint256 boosterReward, uint256 duration); event RewardsEmissionEnded(uint256 amount); event BoosterRewardSet(address token); event WithdrawalFeesSet(uint256[] _feeSchedule, uint256[] _withdrawalFees); event FeesCollected(address indexed user, uint256 amount); event FeesRecovered(uint256 amount); }
[{"inputs":[{"internalType":"address","name":"_rewardsToken","type":"address"},{"internalType":"address","name":"_stakingToken","type":"address"},{"internalType":"address","name":"_boosterToken","type":"address"},{"internalType":"uint256","name":"_rewardsDuration","type":"uint256"},{"internalType":"uint256[]","name":"_feeSchedule","type":"uint256[]"},{"internalType":"uint256[]","name":"_withdrawalFeesPct","type":"uint256[]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"BoosterRewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"}],"name":"BoosterRewardSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FeesCollected","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FeesRecovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LeftoverBoosterRecovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LeftoverRewardRecovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newDuration","type":"uint256"}],"name":"RewardsDurationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardsEmissionEnded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"boosterReward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"}],"name":"RewardsEmissionStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"_feeSchedule","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"_withdrawalFees","type":"uint256[]"}],"name":"WithdrawalFeesSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"boosterEarned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"boosterRewardPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"boosterRewardPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"boosterRewardRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"boosterRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"boosterToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"earned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"exit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"exitFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"withdrawalAmount","type":"uint256"}],"name":"fee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"feeSchedule","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBoosterReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getBoosterRewardForDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getRewardForDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastStakedTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastTimeRewardApplicable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastUpdateTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxWithdrawalFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"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":[],"name":"periodFinish","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"recoverFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"recoverLeftoverBooster","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"recoverLeftoverReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"reward","type":"uint256"},{"internalType":"uint256","name":"boosterReward","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"}],"name":"sendRewardsAndStartEmission","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_boosterToken","type":"address"}],"name":"setBoosterToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"duration","type":"uint256"}],"name":"setRewardsDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_feeSchedule","type":"uint256[]"},{"internalType":"uint256[]","name":"_withdrawalFees","type":"uint256[]"}],"name":"setWithdrawalFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"stakeWithPermit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"reward","type":"uint256"},{"internalType":"uint256","name":"boosterReward","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"}],"name":"startEmission","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stopEmission","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userBoosterRewardPerTokenPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userRewardPerTokenPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"withdrawalFeesPct","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalFeesUnit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60c06040526127106010556103e86011553480156200001d57600080fd5b5060405162003dc238038062003dc283398101604081905262000040916200063d565b60016000556200005033620001e5565b6001805460ff60a01b191690556001600160a01b0380871690851603620000d35760405162461bcd60e51b8152602060048201526039602482015260008051602062003da283398151915260448201527f656e742066726f6d207468652072657761726420746f6b656e0000000000000060648201526084015b60405180910390fd5b846001600160a01b0316846001600160a01b0316036200014b5760405162461bcd60e51b815260206004820152603a602482015260008051602062003da283398151915260448201527f656e742066726f6d20746865207374616b696e6720746f6b656e0000000000006064820152608401620000ca565b600083116200019d5760405162461bcd60e51b815260206004820152601f60248201527f52657761726473206475726174696f6e2063616e6e6f74206265207a65726f006044820152606401620000ca565b6001600160a01b0386811660805285811660a052600980546001600160a01b0319169186169190911790556004839055620001d9828262000237565b505050505050620007ba565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b8051825114620002a1576040805162461bcd60e51b815260206004820152602481019190915260008051602062003d8283398151915260448201527f20617272617973206d757374206265207468652073616d65206c656e677468216064820152608401620000ca565b600a825111156200031c5760405162461bcd60e51b8152602060048201526049602482015260008051602062003d8283398151915260448201527f20617272617973206c656e677468732063616e6e6f74206265206c6172676572606482015268207468616e2031302160b81b608482015260a401620000ca565b6000806011546001620003309190620006fe565b905060005b845181101562000491578285828151811062000355576200035562000719565b602002602001015111620003ac5760405162461bcd60e51b815260206004820152601f60248201527f466565207363686564756c65206d75737420626520617363656e64696e6721006044820152606401620000ca565b81848281518110620003c257620003c262000719565b6020026020010151106200043f5760405162461bcd60e51b815260206004820152603a60248201527f5769746864726177616c2066656573206d7573742062652064657363656e646960448201527f6e6720616e64206c6f776572207468616e206d6178696d756d210000000000006064820152608401620000ca565b84818151811062000454576200045462000719565b6020026020010151925083818151811062000473576200047362000719565b602002602001015191508062000489906200072f565b905062000335565b508351620004a790600e906020870190620004ff565b508251620004bd90600f906020860190620004ff565b507fe5a2c1e4acf2a2da539a1183c56fbbcec4b66dbc828b76f1c1bf365f1887886b8484604051620004f192919062000788565b60405180910390a150505050565b8280548282559060005260206000209081019282156200053d579160200282015b828111156200053d57825182559160200191906001019062000520565b506200054b9291506200054f565b5090565b5b808211156200054b576000815560010162000550565b80516001600160a01b03811681146200057e57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620005ab57600080fd5b815160206001600160401b0380831115620005ca57620005ca62000583565b8260051b604051601f19603f83011681018181108482111715620005f257620005f262000583565b6040529384528581018301938381019250878511156200061157600080fd5b83870191505b84821015620006325781518352918301919083019062000617565b979650505050505050565b60008060008060008060c087890312156200065757600080fd5b620006628762000566565b9550620006726020880162000566565b9450620006826040880162000566565b6060880151608089015191955093506001600160401b0380821115620006a757600080fd5b620006b58a838b0162000599565b935060a0890151915080821115620006cc57600080fd5b50620006db89828a0162000599565b9150509295509295509295565b634e487b7160e01b600052601160045260246000fd5b60008219821115620007145762000714620006e8565b500190565b634e487b7160e01b600052603260045260246000fd5b600060018201620007445762000744620006e8565b5060010190565b600081518084526020808501945080840160005b838110156200077d578151875295820195908201906001016200075f565b509495945050505050565b6040815260006200079d60408301856200074b565b8281036020840152620007b181856200074b565b95945050505050565b60805160a0516135246200085e6000396000818161050f01528181610c840152818161160f0152818161199e01528181611bc201528181611e7301528181611ee60152818161242c0152612ae601526000818161066d0152818161086d015281816109cc01528181610cae01528181610d8801528181610e10015281816110dc0152818161134d0152818161156801528181612a6f0152612b1001526135246000f3fe608060405234801561001057600080fd5b50600436106103615760003560e01c80637b0a47ee116101c8578063c8f33c9111610104578063ebe2b12b116100a2578063f22797d81161007c578063f22797d8146106c5578063f2fde38b146106e5578063f3f0ffda146106f8578063faef375e1461070057600080fd5b8063ebe2b12b146106a0578063ec1c0a99146106a9578063ecd9ba82146106b257600080fd5b8063cdeae371116100de578063cdeae37114610660578063d1af0c7d14610668578063df136d651461068f578063e9fad8ee1461069857600080fd5b8063c8f33c911461063c578063cc1a378f14610645578063cd3daf9d1461065857600080fd5b80638da5cb5b116101715780639e6eda181161014b5780639e6eda18146105ed578063a694fc3a14610600578063be0bf75114610613578063c57a202c1461061c57600080fd5b80638da5cb5b146105b65780638f0bb79c146105c75780639465d4a1146105da57600080fd5b80638980f11f116101a25780638980f11f146105705780638b876347146105835780638bb95b45146105a357600080fd5b80637b0a47ee1461055757806380faa57d146105605780638456cb591461056857600080fd5b80633b8e4f7e116102a25780636439ea4c11610240578063715018a61161021a578063715018a61461050257806372f702f31461050a5780637707513014610531578063771916051461054457600080fd5b80636439ea4c146104c857806366a03c7f146104d057806370a08231146104d957600080fd5b80635312ea8e1161027c5780635312ea8e1461044d578063576c23ab146104605780635c975abb1461048b5780635d129544146104a857600080fd5b80633b8e4f7e1461042a5780633d18b9121461043d5780633f4ba83a1461044557600080fd5b80631c1f78eb1161030f5780632e1a7d4d116102e95780632e1a7d4d146103f257806335ceec0f14610405578063386a9525146104185780633b7d27fe1461042157600080fd5b80631c1f78eb146103da5780632459a699146103e25780632cbe61d3146103ea57600080fd5b806310cbbe381161034057806310cbbe38146103b657806313114a9d146103c957806318160ddd146103d257600080fd5b80628cc262146103665780630700037d1461038c5780630e9bb0a3146103ac575b600080fd5b610379610374366004613117565b610708565b6040519081526020015b60405180910390f35b61037961039a366004613117565b60086020526000908152604090205481565b6103b4610785565b005b6103796103c4366004613117565b610a72565b61037960135481565b601454610379565b610379610a96565b6103b4610aad565b6103b4610c2f565b6103b4610400366004613132565b610e6e565b610379610413366004613132565b610f68565b61037960045481565b61037960105481565b610379610438366004613117565b610f89565b6103b4610fbf565b6103b461113d565b6103b461045b366004613132565b61118f565b600954610473906001600160a01b031681565b6040516001600160a01b039091168152602001610383565b600154600160a01b900460ff166040519015158152602001610383565b6103796104b6366004613117565b600c6020526000908152604090205481565b6103796111ef565b610379600b5481565b6103796104e7366004613117565b6001600160a01b031660009081526015602052604090205490565b6103b4611250565b6104737f000000000000000000000000000000000000000000000000000000000000000081565b6103b461053f3660046131f1565b6112a2565b6103b4610552366004613255565b6112f8565b61037960035481565b6103796113cd565b6103b46113db565b6103b461057e366004613281565b61142b565b610379610591366004613117565b60076020526000908152604090205481565b6103b46105b1366004613255565b6114c6565b6001546001600160a01b0316610473565b6103796105d5366004613132565b61150e565b6103b46105e8366004613117565b61151e565b6103796105fb366004613281565b61170f565b6103b461060e366004613132565b6117bd565b610379600a5481565b61037961062a366004613117565b60126020526000908152604090205481565b61037960055481565b6103b4610653366004613132565b611a00565b610379611af1565b6103b4611b52565b6104737f000000000000000000000000000000000000000000000000000000000000000081565b61037960065481565b6103b4611c19565b61037960025481565b61037960115481565b6103b46106c03660046132ab565b611c42565b6103796106d3366004613117565b600d6020526000908152604090205481565b6103b46106f3366004613117565b611f59565b610379612026565b6103b4612038565b6001600160a01b0381166000908152600860209081526040808320546007909252822054670de0b6b3a76400009061073e611af1565b6107489190613310565b6001600160a01b03851660009081526015602052604090205461076b9190613327565b6107759190613346565b61077f9190613368565b92915050565b6001546001600160a01b031633146107d25760405162461bcd60e51b815260206004820181905260248201526000805160206134cf83398151915260448201526064015b60405180910390fd5b600254421061084b576040805162461bcd60e51b81526020600482015260248101919091527f43616e6e6f742073746f70207265776172647320656d697373696f6e7320696660448201527f206e6f742073746172746564206f7220616c72656164792066696e697368656460648201526084016107c9565b60008060145460000361096f576040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156108bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108e09190613380565b6009549092506001600160a01b031615610967576009546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa15801561093c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109609190613380565b90506109a3565b5060006109a3565b60004260025461097f9190613310565b90508060035461098f9190613327565b925080600a5461099f9190613327565b9150505b4260025581156109f3576109f36109c26001546001600160a01b031690565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169084612258565b6009546001600160a01b031615801590610a0d5750600081115b15610a3a57610a3a610a276001546001600160a01b031690565b6009546001600160a01b03169083612258565b6040518281527f6d815f6a8a51efb6f4140923189859b9e9caaa228c9334179e8eb7edefc6838e906020015b60405180910390a15050565b6001600160a01b03811660009081526015602052604081205461077f90839061170f565b6000600454600354610aa89190613327565b905090565b600260005403610aff5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016107c9565b600260005533610b0d611af1565b600655610b186111ef565b600b55610b236113cd565b6005556001600160a01b03811615610b9e57610b3e81610708565b6001600160a01b038216600090815260086020908152604080832093909355600654600790915291902055610b7281610f89565b6001600160a01b0382166000908152600d6020908152604080832093909355600b54600c909152919020555b6009546001600160a01b031615610c2757336000908152600d60205260409020548015610c2557336000818152600d6020526040812055600954610bee916001600160a01b039091169083612258565b60405181815233907fd1e5531ac01ffc9c7971b52c82806a6e5ae8907ddedd2e3153afaafcfdf175d6906020015b60405180910390a25b505b506001600055565b6001546001600160a01b03163314610c775760405162461bcd60e51b815260206004820181905260248201526000805160206134cf83398151915260448201526064016107c9565b601454158015610cd857507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316145b610d705760405162461bcd60e51b815260206004820152605e60248201527f43616e6e6f74207265636f766572206c6566746f76657220726577617264206960448201527f66206974206973206e6f7420746865207374616b696e6720746f6b656e206f7260648201527f20746865726520617265207374696c6c207374616b656420746f6b656e730000608482015260a4016107c9565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610dd7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dfb9190613380565b90508015610e3757610e376001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163383612258565b6040518181527ff6d91c6a1bf05d7c0f2c157905a97d3bc2f860a1402d71dd52a27fabb5bcaf8d906020015b60405180910390a150565b600260005403610ec05760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016107c9565b600260005533610ece611af1565b600655610ed96111ef565b600b55610ee46113cd565b6005556001600160a01b03811615610f5f57610eff81610708565b6001600160a01b038216600090815260086020908152604080832093909355600654600790915291902055610f3381610f89565b6001600160a01b0382166000908152600d6020908152604080832093909355600b54600c909152919020555b610c2582612301565b600e8181548110610f7857600080fd5b600091825260209091200154905081565b6001600160a01b0381166000908152600d6020908152604080832054600c909252822054670de0b6b3a76400009061073e6111ef565b6002600054036110115760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016107c9565b60026000553361101f611af1565b60065561102a6111ef565b600b556110356113cd565b6005556001600160a01b038116156110b05761105081610708565b6001600160a01b03821660009081526008602090815260408083209390935560065460079091529190205561108481610f89565b6001600160a01b0382166000908152600d6020908152604080832093909355600b54600c909152919020555b336000908152600860205260409020548015610c25573360008181526008602052604081205561110b907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169083612258565b60405181815233907fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e048690602001610c1c565b6001546001600160a01b031633146111855760405162461bcd60e51b815260206004820181905260248201526000805160206134cf83398151915260448201526064016107c9565b61118d6124db565b565b6002600054036111e15760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016107c9565b6002600055610c2781612301565b60006014546000036112025750600b5490565b601454600a546005546112136113cd565b61121d9190613310565b6112279190613327565b61123990670de0b6b3a7640000613327565b6112439190613346565b600b54610aa89190613368565b6001546001600160a01b031633146112985760405162461bcd60e51b815260206004820181905260248201526000805160206134cf83398151915260448201526064016107c9565b61118d6000612581565b6001546001600160a01b031633146112ea5760405162461bcd60e51b815260206004820181905260248201526000805160206134cf83398151915260448201526064016107c9565b6112f482826125e0565b5050565b6001546001600160a01b031633146113405760405162461bcd60e51b815260206004820181905260248201526000805160206134cf83398151915260448201526064016107c9565b6113756001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163330866128be565b6009546001600160a01b03161580159061138f5750600082115b156113bd576113bd6113a96001546001600160a01b031690565b6009546001600160a01b03169030856128be565b6113c883838361290f565b505050565b6000610aa842600254612d49565b6001546001600160a01b031633146114235760405162461bcd60e51b815260206004820181905260248201526000805160206134cf83398151915260448201526064016107c9565b61118d612d61565b6001546001600160a01b031633146114735760405162461bcd60e51b815260206004820181905260248201526000805160206134cf83398151915260448201526064016107c9565b6114876001600160a01b0383163383612258565b604080516001600160a01b0384168152602081018390527f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa289101610a66565b6001546001600160a01b031633146113bd5760405162461bcd60e51b815260206004820181905260248201526000805160206134cf83398151915260448201526064016107c9565b600f8181548110610f7857600080fd5b6001546001600160a01b031633146115665760405162461bcd60e51b815260206004820181905260248201526000805160206134cf83398151915260448201526064016107c9565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b03160361160d5760405162461bcd60e51b815260206004820152603960248201527f54686520626f6f7374657220746f6b656e206d7573742062652064696666657260448201527f656e742066726f6d207468652072657761726420746f6b656e0000000000000060648201526084016107c9565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b0316036116b45760405162461bcd60e51b815260206004820152603a60248201527f54686520626f6f7374657220746f6b656e206d7573742062652064696666657260448201527f656e742066726f6d20746865207374616b696e6720746f6b656e00000000000060648201526084016107c9565b6009805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527f0c6fec5b80219c372da56cb4d1ef3e172069953fa5c72ececf0d0dfe1109260b90602001610e63565b6000805b600e548110156117b357600e818154811061173057611730613399565b60009182526020808320909101546001600160a01b0387168352601290915260409091205461175f9042613310565b10156117a357601054600f828154811061177b5761177b613399565b9060005260206000200154846117919190613327565b61179b9190613346565b91505061077f565b6117ac816133af565b9050611713565b5060009392505050565b60026000540361180f5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016107c9565b6002600055600154600160a01b900460ff16156118615760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016107c9565b3361186a611af1565b6006556118756111ef565b600b556118806113cd565b6005556001600160a01b038116156118fb5761189b81610708565b6001600160a01b0382166000908152600860209081526040808320939093556006546007909152919020556118cf81610f89565b6001600160a01b0382166000908152600d6020908152604080832093909355600b54600c909152919020555b6000821161194b5760405162461bcd60e51b815260206004820152600e60248201527f43616e6e6f74207374616b65203000000000000000000000000000000000000060448201526064016107c9565b816014546119599190613368565b60145533600090815260156020526040902054611977908390613368565b3360008181526015602090815260408083209490945560129052919091204290556119ce907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169030856128be565b60405182815233907f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d90602001610c1c565b6001546001600160a01b03163314611a485760405162461bcd60e51b815260206004820181905260248201526000805160206134cf83398151915260448201526064016107c9565b6002544211611ae55760405162461bcd60e51b815260206004820152605860248201527f50726576696f7573207265776172647320706572696f64206d7573742062652060448201527f636f6d706c657465206265666f7265206368616e67696e67207468652064757260648201527f6174696f6e20666f7220746865206e657720706572696f640000000000000000608482015260a4016107c9565b611aee81612de9565b50565b6000601454600003611b04575060065490565b601454600354600554611b156113cd565b611b1f9190613310565b611b299190613327565b611b3b90670de0b6b3a7640000613327565b611b459190613346565b600654610aa89190613368565b6001546001600160a01b03163314611b9a5760405162461bcd60e51b815260206004820181905260248201526000805160206134cf83398151915260448201526064016107c9565b601380546000909155611be9611bb86001546001600160a01b031690565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169083612258565b6040518181527f6857c770f3cb43e9c19050a37dd914ec876241c1f4b487d26a1d4f5d3054f49b90602001610e63565b33600090815260156020526040902054611c3290610e6e565b611c3a610fbf565b61118d610aad565b600260005403611c945760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016107c9565b6002600055600154600160a01b900460ff1615611ce65760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016107c9565b33611cef611af1565b600655611cfa6111ef565b600b55611d056113cd565b6005556001600160a01b03811615611d8057611d2081610708565b6001600160a01b038216600090815260086020908152604080832093909355600654600790915291902055611d5481610f89565b6001600160a01b0382166000908152600d6020908152604080832093909355600b54600c909152919020555b60008611611dd05760405162461bcd60e51b815260206004820152600e60248201527f43616e6e6f74207374616b65203000000000000000000000000000000000000060448201526064016107c9565b85601454611dde9190613368565b60145533600090815260156020526040902054611dfc908790613368565b33600081815260156020526040908190209290925590517fd505accf0000000000000000000000000000000000000000000000000000000081526004810191909152306024820152604481018790526064810186905260ff8516608482015260a4810184905260c481018390526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063d505accf9060e401600060405180830381600087803b158015611eb757600080fd5b505af1158015611ecb573d6000803e3d6000fd5b5050336000818152601260205260409020429055611f1792507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316915030896128be565b60405186815233907f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d9060200160405180910390a25050600160005550505050565b6001546001600160a01b03163314611fa15760405162461bcd60e51b815260206004820181905260248201526000805160206134cf83398151915260448201526064016107c9565b6001600160a01b03811661201d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016107c9565b611aee81612581565b6000600454600a54610aa89190613327565b6001546001600160a01b031633146120805760405162461bcd60e51b815260206004820181905260248201526000805160206134cf83398151915260448201526064016107c9565b6009546001600160a01b03166121245760405162461bcd60e51b815260206004820152604160248201527f43616e6e6f74207265636f766572206c6566746f76657220626f6f737465722060448201527f696620746865726520776173206e6f20626f6f7374657220746f6b656e20736560648201527f7400000000000000000000000000000000000000000000000000000000000000608482015260a4016107c9565b6014541561219c576040805162461bcd60e51b81526020600482015260248101919091527f43616e6e6f74207265636f766572206c6566746f76657220626f6f737465722060448201527f696620746865726520617265207374696c6c207374616b656420746f6b656e7360648201526084016107c9565b6009546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156121e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122099190613380565b9050801561222857600954612228906001600160a01b03163383612258565b6040518181527fa075ee3dcd38efb87f0f97160a935b6a43768378263338beea06b9681f66151d90602001610e63565b6040516001600160a01b0383166024820152604481018290526113c89084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612e1e565b600081116123515760405162461bcd60e51b815260206004820152601160248201527f43616e6e6f74207769746864726177203000000000000000000000000000000060448201526064016107c9565b33600090815260156020526040902054808211156123d75760405162461bcd60e51b815260206004820152602960248201527f43616e6e6f74207769746864726177206d6f7265207468616e206163636f756e60448201527f742062616c616e6365000000000000000000000000000000000000000000000060648201526084016107c9565b816014546123e59190613310565b60145560006123f4338461170f565b90506124008383613310565b3360009081526015602052604081209190915561241d8285613310565b90506124536001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163383612258565b60405181815233907f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d59060200160405180910390a281156124d55760405182815233907f9dc46f23cfb5ddcad0ae7ea2be38d47fec07bb9382ec7e564efc69e036dd66ce9060200160405180910390a2816013546124d19190613368565b6013555b50505050565b600154600160a01b900460ff166125345760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016107c9565b6001805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600180546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b8051825114612659576040805162461bcd60e51b81526020600482015260248101919091527f466565207363686564756c6520616e64207769746864726177616c206665657360448201527f20617272617973206d757374206265207468652073616d65206c656e6774682160648201526084016107c9565b600a825111156126f75760405162461bcd60e51b815260206004820152604960248201527f466565207363686564756c6520616e64207769746864726177616c206665657360448201527f20617272617973206c656e677468732063616e6e6f74206265206c617267657260648201527f207468616e203130210000000000000000000000000000000000000000000000608482015260a4016107c9565b60008060115460016127099190613368565b905060005b8451811015612856578285828151811061272a5761272a613399565b60200260200101511161277f5760405162461bcd60e51b815260206004820152601f60248201527f466565207363686564756c65206d75737420626520617363656e64696e67210060448201526064016107c9565b8184828151811061279257612792613399565b60200260200101511061280d5760405162461bcd60e51b815260206004820152603a60248201527f5769746864726177616c2066656573206d7573742062652064657363656e646960448201527f6e6720616e64206c6f776572207468616e206d6178696d756d2100000000000060648201526084016107c9565b84818151811061281f5761281f613399565b6020026020010151925083818151811061283b5761283b613399565b602002602001015191508061284f906133af565b905061270e565b50835161286a90600e90602087019061309b565b50825161287e90600f90602086019061309b565b507fe5a2c1e4acf2a2da539a1183c56fbbcec4b66dbc828b76f1c1bf365f1887886b84846040516128b0929190613403565b60405180910390a150505050565b6040516001600160a01b03808516602483015283166044820152606481018290526124d59085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161229d565b6000612919611af1565b6006556129246111ef565b600b5561292f6113cd565b6005556001600160a01b038116156129aa5761294a81610708565b6001600160a01b03821660009081526008602090815260408083209390935560065460079091529190205561297e81610f89565b6001600160a01b0382166000908152600d6020908152604080832093909355600b54600c909152919020555b81156129b9576129b982612de9565b60025442106129e7576004546129cf9085613346565b6003556004546129df9084613346565b600a55612a57565b6000426002546129f79190613310565b9050600060035482612a099190613327565b600454909150612a198288613368565b612a239190613346565b600355600a54600090612a369084613327565b600454909150612a468288613368565b612a509190613346565b600a555050505b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015612abe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ae29190613380565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614612ba057600454612b4a9082613346565b6003541115612b9b5760405162461bcd60e51b815260206004820152601860248201527f50726f76696465642072657761726420746f6f2068696768000000000000000060448201526064016107c9565b612c0b565b600454601454612bb09083613310565b612bba9190613346565b6003541115612c0b5760405162461bcd60e51b815260206004820152601860248201527f50726f76696465642072657761726420746f6f2068696768000000000000000060448201526064016107c9565b6009546001600160a01b031615612cec576009546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612c65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c899190613380565b905060045481612c999190613346565b600a541115612cea5760405162461bcd60e51b815260206004820181905260248201527f50726f766964656420626f6f737465722072657761726420746f6f206869676860448201526064016107c9565b505b426005819055600454612cfe91613368565b60025560408051868152602081018690529081018490527f748824204e79acdab8f1a9977cbc584250e206ad90d05ef198799f9d6ee93a7d9060600160405180910390a15050505050565b6000818310612d585781612d5a565b825b9392505050565b600154600160a01b900460ff1615612dae5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016107c9565b6001805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586125643390565b60048190556040518181527ffb46ca5a5e06d4540d6387b930a7c978bce0db5f449ec6b3f5d07c6e1d44f2d390602001610e63565b6000612e73826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612f039092919063ffffffff16565b8051909150156113c85780806020019051810190612e919190613431565b6113c85760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016107c9565b6060612f128484600085612f1a565b949350505050565b606082471015612f925760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016107c9565b6001600160a01b0385163b612fe95760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107c9565b600080866001600160a01b03168587604051613005919061347f565b60006040518083038185875af1925050503d8060008114613042576040519150601f19603f3d011682016040523d82523d6000602084013e613047565b606091505b5091509150613057828286613062565b979650505050505050565b60608315613071575081612d5a565b8251156130815782518084602001fd5b8160405162461bcd60e51b81526004016107c9919061349b565b8280548282559060005260206000209081019282156130d6579160200282015b828111156130d65782518255916020019190600101906130bb565b506130e29291506130e6565b5090565b5b808211156130e257600081556001016130e7565b80356001600160a01b038116811461311257600080fd5b919050565b60006020828403121561312957600080fd5b612d5a826130fb565b60006020828403121561314457600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261317257600080fd5b8135602067ffffffffffffffff8083111561318f5761318f61314b565b8260051b604051601f19603f830116810181811084821117156131b4576131b461314b565b6040529384528581018301938381019250878511156131d257600080fd5b83870191505b84821015613057578135835291830191908301906131d8565b6000806040838503121561320457600080fd5b823567ffffffffffffffff8082111561321c57600080fd5b61322886838701613161565b9350602085013591508082111561323e57600080fd5b5061324b85828601613161565b9150509250929050565b60008060006060848603121561326a57600080fd5b505081359360208301359350604090920135919050565b6000806040838503121561329457600080fd5b61329d836130fb565b946020939093013593505050565b600080600080600060a086880312156132c357600080fd5b8535945060208601359350604086013560ff811681146132e257600080fd5b94979396509394606081013594506080013592915050565b634e487b7160e01b600052601160045260246000fd5b600082821015613322576133226132fa565b500390565b6000816000190483118215151615613341576133416132fa565b500290565b60008261336357634e487b7160e01b600052601260045260246000fd5b500490565b6000821982111561337b5761337b6132fa565b500190565b60006020828403121561339257600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b6000600182016133c1576133c16132fa565b5060010190565b600081518084526020808501945080840160005b838110156133f8578151875295820195908201906001016133dc565b509495945050505050565b60408152600061341660408301856133c8565b828103602084015261342881856133c8565b95945050505050565b60006020828403121561344357600080fd5b81518015158114612d5a57600080fd5b60005b8381101561346e578181015183820152602001613456565b838111156124d55750506000910152565b60008251613491818460208701613453565b9190910192915050565b60208152600082518060208401526134ba816040850160208701613453565b601f01601f1916919091016040019291505056fe4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a2646970667358221220f1782956c14f05a3ad891819b987778508dbc25a816f61f86c1be51a059aafaa64736f6c634300080d0033466565207363686564756c6520616e64207769746864726177616c206665657354686520626f6f7374657220746f6b656e206d75737420626520646966666572000000000000000000000000eeeeeb57642040be42185f49c52f7e9b38f8eeee000000000000000000000000eeeeeb57642040be42185f49c52f7e9b38f8eeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013c68000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000e100000000000000000000000000000000000000000000000000000000000093a800000000000000000000000000000000000000000000000000000000000278d00000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000000000000000000c80000000000000000000000000000000000000000000000000000000000000064
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000eeeeeb57642040be42185f49c52f7e9b38f8eeee000000000000000000000000eeeeeb57642040be42185f49c52f7e9b38f8eeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013c68000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000e100000000000000000000000000000000000000000000000000000000000093a800000000000000000000000000000000000000000000000000000000000278d00000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000000000000000000c80000000000000000000000000000000000000000000000000000000000000064
-----Decoded View---------------
Arg [0] : _rewardsToken (address): 0xeeeeeb57642040be42185f49c52f7e9b38f8eeee
Arg [1] : _stakingToken (address): 0xeeeeeb57642040be42185f49c52f7e9b38f8eeee
Arg [2] : _boosterToken (address): 0x0000000000000000000000000000000000000000
Arg [3] : _rewardsDuration (uint256): 1296000
Arg [4] : _feeSchedule (uint256[]): 3600,604800,2592000
Arg [5] : _withdrawalFeesPct (uint256[]): 500,200,100
-----Encoded View---------------
14 Constructor Arguments found :
Arg [0] : 000000000000000000000000eeeeeb57642040be42185f49c52f7e9b38f8eeee
Arg [1] : 000000000000000000000000eeeeeb57642040be42185f49c52f7e9b38f8eeee
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [3] : 000000000000000000000000000000000000000000000000000000000013c680
Arg [4] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000140
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000e10
Arg [8] : 0000000000000000000000000000000000000000000000000000000000093a80
Arg [9] : 0000000000000000000000000000000000000000000000000000000000278d00
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [11] : 00000000000000000000000000000000000000000000000000000000000001f4
Arg [12] : 00000000000000000000000000000000000000000000000000000000000000c8
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000064
Deployed ByteCode Sourcemap
26573:16289:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29371:188;;;;;;:::i;:::-;;:::i;:::-;;;552:25:1;;;540:2;525:18;29371:188:0;;;;;;;;27067:42;;;;;;:::i;:::-;;;;;;;;;;;;;;34492:1130;;;:::i;:::-;;30365:124;;;;;;:::i;:::-;;:::i;27649:24::-;;;;;;28718:93;28791:12;;28718:93;;29567:118;;;:::i;33270:422::-;;;:::i;35851:461::-;;;:::i;31983:115::-;;;;;;:::i;:::-;;:::i;27370:28::-;;;;;;:::i;:::-;;:::i;26886:30::-;;;;;;27446:41;;;;;;30001:216;;;;;;:::i;:::-;;:::i;32955:307::-;;;:::i;37893:67::-;;;:::i;32106:101::-;;;;;;:::i;:::-;;:::i;27118:26::-;;;;;-1:-1:-1;;;;;27118:26:0;;;;;;-1:-1:-1;;;;;951:55:1;;;933:74;;921:2;906:18;27118:26:0;773:240:1;22754:86:0;22825:7;;-1:-1:-1;;;22825:7:0;;;;22754:86;;1183:14:1;;1176:22;1158:41;;1146:2;1131:18;22754:86:0;1018:187:1;27241:64:0;;;;;;:::i;:::-;;;;;;;;;;;;;;29693:300;;;:::i;27190:42::-;;;;;;28819:112;;;;;;:::i;:::-;-1:-1:-1;;;;;28905:18:0;28878:7;28905:18;;;:9;:18;;;;;;;28819:112;25659:103;;;:::i;26777:36::-;;;;;37994:179;;;;;;:::i;:::-;;:::i;33890:421::-;;;;;;:::i;:::-;;:::i;26854:25::-;;;;;;28939:131;;;:::i;37822:63::-;;;:::i;35630:213::-;;;;;;:::i;:::-;;:::i;27003:57::-;;;;;;:::i;:::-;;;;;;;;;;;;;;34319:165;;;;;;:::i;:::-;;:::i;25008:87::-;25081:6;;-1:-1:-1;;;;;25081:6:0;25008:87;;27405:34;;;;;;:::i;:::-;;:::i;37406:408::-;;;;;;:::i;:::-;;:::i;30497:359::-;;;;;;:::i;:::-;;:::i;30918:432::-;;;;;;:::i;:::-;;:::i;27151:32::-;;;;;;27593:49;;;;;;:::i;:::-;;;;;;;;;;;;;;26923:29;;;;;;37080:292;;;;;;:::i;:::-;;:::i;29078:285::-;;;:::i;36853:219::-;;;:::i;26734:36::-;;;;;26959:35;;;;;;33700:126;;;:::i;26820:27::-;;;;;;27511:38;;;;;;31358:617;;;;;;:::i;:::-;;:::i;27312:49::-;;;;;;:::i;:::-;;;;;;;;;;;;;;25917:201;;;;;;:::i;:::-;;:::i;30225:132::-;;;:::i;36320:525::-;;;:::i;29371:188::-;-1:-1:-1;;;;;29535:16:0;;29425:7;29535:16;;;:7;:16;;;;;;;;;29493:22;:31;;;;;;29528:4;;29474:16;:14;:16::i;:::-;:50;;;;:::i;:::-;-1:-1:-1;;;;;29452:18:0;;;;;;:9;:18;;;;;;:73;;;;:::i;:::-;:80;;;;:::i;:::-;:99;;;;:::i;:::-;29445:106;29371:188;-1:-1:-1;;29371:188:0:o;34492:1130::-;25081:6;;-1:-1:-1;;;;;25081:6:0;21482:10;25228:23;25220:68;;;;-1:-1:-1;;;25220:68:0;;5371:2:1;25220:68:0;;;5353:21:1;;;5390:18;;;5383:30;-1:-1:-1;;;;;;;;;;;5429:18:1;;;5422:62;5501:18;;25220:68:0;;;;;;;;;34572:12:::1;;34554:15;:30;34546:107;;;::::0;;-1:-1:-1;;;34546:107:0;;5732:2:1;34546:107:0::1;::::0;::::1;5714:21:1::0;5751:18;;;5744:30;;;;5810:34;5790:18;;;5783:62;5881:34;5861:18;;;5854:62;5933:19;;34546:107:0::1;5530:428:1::0;34546:107:0::1;34666:20;34697:27:::0;34741:12:::1;;34757:1;34741:17:::0;34737:516:::1;;34790:37;::::0;-1:-1:-1;;;34790:37:0;;34821:4:::1;34790:37;::::0;::::1;933:74:1::0;34790:12:0::1;-1:-1:-1::0;;;;;34790:22:0::1;::::0;::::1;::::0;906:18:1;;34790:37:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;34854:12;::::0;34775:52;;-1:-1:-1;;;;;;34854:12:0::1;34846:35:::0;34842:199:::1;;34924:12;::::0;:37:::1;::::0;-1:-1:-1;;;34924:37:0;;34955:4:::1;34924:37;::::0;::::1;933:74:1::0;-1:-1:-1;;;;;34924:12:0;;::::1;::::0;:22:::1;::::0;906:18:1;;34924:37:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;34902:59;;34737:516;;34842:199;-1:-1:-1::0;35024:1:0::1;34737:516;;;35073:17;35108:15;35093:12;;:30;;;;:::i;:::-;35073:50;;35166:9;35153:10;;:22;;;;:::i;:::-;35138:37;;35232:9;35212:17;;:29;;;;:::i;:::-;35190:51;;35058:195;34737:516;35280:15;35265:12;:30:::0;35310:16;;35306:97:::1;;35343:48;35369:7;25081:6:::0;;-1:-1:-1;;;;;25081:6:0;;25008:87;35369:7:::1;-1:-1:-1::0;;;;;35343:12:0::1;:25;::::0;35378:12;35343:25:::1;:48::i;:::-;35425:12;::::0;-1:-1:-1;;;;;35425:12:0::1;35417:35:::0;;::::1;::::0;:62:::1;;;35478:1;35456:19;:23;35417:62;35413:150;;;35496:55;35522:7;25081:6:::0;;-1:-1:-1;;;;;25081:6:0;;25008:87;35522:7:::1;35496:12;::::0;-1:-1:-1;;;;;35496:12:0::1;::::0;35531:19;35496:25:::1;:55::i;:::-;35580:34;::::0;552:25:1;;;35580:34:0::1;::::0;540:2:1;525:18;35580:34:0::1;;;;;;;;34535:1087;;34492:1130::o:0;30365:124::-;-1:-1:-1;;;;;30462:18:0;;30422:7;30462:18;;;:9;:18;;;;;;30449:32;;30453:7;;30449:3;:32::i;29567:118::-;29622:7;29662:15;;29649:10;;:28;;;;:::i;:::-;29642:35;;29567:118;:::o;33270:422::-;18467:1;19065:7;;:19;19057:63;;;;-1:-1:-1;;;19057:63:0;;6354:2:1;19057:63:0;;;6336:21:1;6393:2;6373:18;;;6366:30;6432:33;6412:18;;;6405:61;6483:18;;19057:63:0;6152:355:1;19057:63:0;18467:1;19198:7;:18;33331:10:::1;41516:16;:14;:16::i;:::-;41493:20;:39:::0;41573:23:::1;:21;:23::i;:::-;41543:27;:53:::0;41624:26:::1;:24;:26::i;:::-;41607:14;:43:::0;-1:-1:-1;;;;;41665:21:0;::::1;::::0;41661:303:::1;;41722:15;41729:7;41722:6;:15::i;:::-;-1:-1:-1::0;;;;;41703:16:0;::::1;;::::0;;;:7:::1;:16;::::0;;;;;;;:34;;;;41786:20:::1;::::0;41752:22:::1;:31:::0;;;;;;:54;41847:22:::1;41711:7:::0;41847:13:::1;:22::i;:::-;-1:-1:-1::0;;;;;41821:23:0;::::1;;::::0;;;:14:::1;:23;::::0;;;;;;;:48;;;;41925:27:::1;::::0;41884:29:::1;:38:::0;;;;;;:68;41661:303:::1;33366:12:::2;::::0;-1:-1:-1;;;;;33366:12:0::2;33358:35:::0;33354:331:::2;;33442:10;33410:14;33427:26:::0;;;:14:::2;:26;::::0;;;;;33472:10;;33468:206:::2;;33518:10;33532:1;33503:26:::0;;;:14:::2;:26;::::0;;;;:30;33552:12:::2;::::0;:45:::2;::::0;-1:-1:-1;;;;;33552:12:0;;::::2;::::0;33590:6;33552:25:::2;:45::i;:::-;33621:37;::::0;552:25:1;;;33639:10:0::2;::::0;33621:37:::2;::::0;540:2:1;525:18;33621:37:0::2;;;;;;;;33468:206;33395:290;33354:331;-1:-1:-1::0;18423:1:0;19377:7;:22;33270:422::o;35851:461::-;25081:6;;-1:-1:-1;;;;;25081:6:0;21482:10;25228:23;25220:68;;;;-1:-1:-1;;;25220:68:0;;5371:2:1;25220:68:0;;;5353:21:1;;;5390:18;;;5383:30;-1:-1:-1;;;;;;;;;;;5429:18:1;;;5422:62;5501:18;;25220:68:0;5169:356:1;25220:68:0;35922:12:::1;::::0;:17;:49;::::1;;;;35959:12;-1:-1:-1::0;;;;;35943:28:0::1;:12;-1:-1:-1::0;;;;;35943:28:0::1;;35922:49;35914:156;;;::::0;-1:-1:-1;;;35914:156:0;;6714:2:1;35914:156:0::1;::::0;::::1;6696:21:1::0;6753:2;6733:18;;;6726:30;6792:34;6772:18;;;6765:62;6863:34;6843:18;;;6836:62;6935:32;6914:19;;;6907:61;6985:19;;35914:156:0::1;6512:498:1::0;35914:156:0::1;36104:37;::::0;-1:-1:-1;;;36104:37:0;;36135:4:::1;36104:37;::::0;::::1;933:74:1::0;36081:20:0::1;::::0;36104:12:::1;-1:-1:-1::0;;;;;36104:22:0::1;::::0;::::1;::::0;906:18:1;;36104:37:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;36081:60:::0;-1:-1:-1;36156:16:0;;36152:100:::1;;36189:51;-1:-1:-1::0;;;;;36189:12:0::1;:25;36215:10;36227:12:::0;36189:25:::1;:51::i;:::-;36267:37;::::0;552:25:1;;;36267:37:0::1;::::0;540:2:1;525:18;36267:37:0::1;;;;;;;;35903:409;35851:461::o:0;31983:115::-;18467:1;19065:7;;:19;19057:63;;;;-1:-1:-1;;;19057:63:0;;6354:2:1;19057:63:0;;;6336:21:1;6393:2;6373:18;;;6366:30;6432:33;6412:18;;;6405:61;6483:18;;19057:63:0;6152:355:1;19057:63:0;18467:1;19198:7;:18;32050:10:::1;41516:16;:14;:16::i;:::-;41493:20;:39:::0;41573:23:::1;:21;:23::i;:::-;41543:27;:53:::0;41624:26:::1;:24;:26::i;:::-;41607:14;:43:::0;-1:-1:-1;;;;;41665:21:0;::::1;::::0;41661:303:::1;;41722:15;41729:7;41722:6;:15::i;:::-;-1:-1:-1::0;;;;;41703:16:0;::::1;;::::0;;;:7:::1;:16;::::0;;;;;;;:34;;;;41786:20:::1;::::0;41752:22:::1;:31:::0;;;;;;:54;41847:22:::1;41711:7:::0;41847:13:::1;:22::i;:::-;-1:-1:-1::0;;;;;41821:23:0;::::1;;::::0;;;:14:::1;:23;::::0;;;;;;;:48;;;;41925:27:::1;::::0;41884:29:::1;:38:::0;;;;;;:68;41661:303:::1;32073:17:::2;32083:6;32073:9;:17::i;27370:28::-:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;27370:28:0;:::o;30001:216::-;-1:-1:-1;;;;;30186:23:0;;30062:7;30186:23;;;:14;:23;;;;;;;;;30137:29;:38;;;;;;30179:4;;30111:23;:21;:23::i;32955:307::-;18467:1;19065:7;;:19;19057:63;;;;-1:-1:-1;;;19057:63:0;;6354:2:1;19057:63:0;;;6336:21:1;6393:2;6373:18;;;6366:30;6432:33;6412:18;;;6405:61;6483:18;;19057:63:0;6152:355:1;19057:63:0;18467:1;19198:7;:18;33009:10:::1;41516:16;:14;:16::i;:::-;41493:20;:39:::0;41573:23:::1;:21;:23::i;:::-;41543:27;:53:::0;41624:26:::1;:24;:26::i;:::-;41607:14;:43:::0;-1:-1:-1;;;;;41665:21:0;::::1;::::0;41661:303:::1;;41722:15;41729:7;41722:6;:15::i;:::-;-1:-1:-1::0;;;;;41703:16:0;::::1;;::::0;;;:7:::1;:16;::::0;;;;;;;:34;;;;41786:20:::1;::::0;41752:22:::1;:31:::0;;;;;;:54;41847:22:::1;41711:7:::0;41847:13:::1;:22::i;:::-;-1:-1:-1::0;;;;;41821:23:0;::::1;;::::0;;;:14:::1;:23;::::0;;;;;;;:48;;;;41925:27:::1;::::0;41884:29:::1;:38:::0;;;;;;:68;41661:303:::1;33057:10:::2;33032:14;33049:19:::0;;;:7:::2;:19;::::0;;;;;33083:10;;33079:176:::2;;33118:10;33132:1;33110:19:::0;;;:7:::2;:19;::::0;;;;:23;33148:45:::2;::::0;:12:::2;-1:-1:-1::0;;;;;33148:25:0::2;::::0;33186:6;33148:25:::2;:45::i;:::-;33213:30;::::0;552:25:1;;;33224:10:0::2;::::0;33213:30:::2;::::0;540:2:1;525:18;33213:30:0::2;406:177:1::0;37893:67:0;25081:6;;-1:-1:-1;;;;;25081:6:0;21482:10;25228:23;25220:68;;;;-1:-1:-1;;;25220:68:0;;5371:2:1;25220:68:0;;;5353:21:1;;;5390:18;;;5383:30;-1:-1:-1;;;;;;;;;;;5429:18:1;;;5422:62;5501:18;;25220:68:0;5169:356:1;25220:68:0;37942:10:::1;:8;:10::i;:::-;37893:67::o:0;32106:101::-;18467:1;19065:7;;:19;19057:63;;;;-1:-1:-1;;;19057:63:0;;6354:2:1;19057:63:0;;;6336:21:1;6393:2;6373:18;;;6366:30;6432:33;6412:18;;;6405:61;6483:18;;19057:63:0;6152:355:1;19057:63:0;18467:1;19198:7;:18;32182:17:::1;32192:6:::0;32182:9:::1;:17::i;29693:300::-:0;29747:7;29771:12;;29787:1;29771:17;29767:84;;-1:-1:-1;29812:27:0;;;29693:300::o;29767:84::-;29973:12;;29946:17;;29928:14;;29899:26;:24;:26::i;:::-;:43;;;;:::i;:::-;29898:65;;;;:::i;:::-;:72;;29966:4;29898:72;:::i;:::-;:87;;;;:::i;:::-;29868:27;;:117;;;;:::i;25659:103::-;25081:6;;-1:-1:-1;;;;;25081:6:0;21482:10;25228:23;25220:68;;;;-1:-1:-1;;;25220:68:0;;5371:2:1;25220:68:0;;;5353:21:1;;;5390:18;;;5383:30;-1:-1:-1;;;;;;;;;;;5429:18:1;;;5422:62;5501:18;;25220:68:0;5169:356:1;25220:68:0;25724:30:::1;25751:1;25724:18;:30::i;37994:179::-:0;25081:6;;-1:-1:-1;;;;;25081:6:0;21482:10;25228:23;25220:68;;;;-1:-1:-1;;;25220:68:0;;5371:2:1;25220:68:0;;;5353:21:1;;;5390:18;;;5383:30;-1:-1:-1;;;;;;;;;;;5429:18:1;;;5422:62;5501:18;;25220:68:0;5169:356:1;25220:68:0;38116:49:::1;38135:12;38149:15;38116:18;:49::i;:::-;37994:179:::0;;:::o;33890:421::-;25081:6;;-1:-1:-1;;;;;25081:6:0;21482:10;25228:23;25220:68;;;;-1:-1:-1;;;25220:68:0;;5371:2:1;25220:68:0;;;5353:21:1;;;5390:18;;;5383:30;-1:-1:-1;;;;;;;;;;;5429:18:1;;;5422:62;5501:18;;25220:68:0;5169:356:1;25220:68:0;34014:64:::1;-1:-1:-1::0;;;;;34014:12:0::1;:29;34044:10;34064:4;34071:6:::0;34014:29:::1;:64::i;:::-;34101:12;::::0;-1:-1:-1;;;;;34101:12:0::1;34093:35:::0;;::::1;::::0;:56:::1;;;34148:1;34132:13;:17;34093:56;34089:157;;;34166:68;34196:7;25081:6:::0;;-1:-1:-1;;;;;25081:6:0;;25008:87;34196:7:::1;34166:12;::::0;-1:-1:-1;;;;;34166:12:0::1;::::0;34213:4:::1;34220:13:::0;34166:29:::1;:68::i;:::-;34256:47;34271:6;34279:13;34294:8;34256:14;:47::i;:::-;33890:421:::0;;;:::o;28939:131::-;28996:7;29023:39;29032:15;29049:12;;29023:8;:39::i;37822:63::-;25081:6;;-1:-1:-1;;;;;25081:6:0;21482:10;25228:23;25220:68;;;;-1:-1:-1;;;25220:68:0;;5371:2:1;25220:68:0;;;5353:21:1;;;5390:18;;;5383:30;-1:-1:-1;;;;;;;;;;;5429:18:1;;;5422:62;5501:18;;25220:68:0;5169:356:1;25220:68:0;37869:8:::1;:6;:8::i;35630:213::-:0;25081:6;;-1:-1:-1;;;;;25081:6:0;21482:10;25228:23;25220:68;;;;-1:-1:-1;;;25220:68:0;;5371:2:1;25220:68:0;;;5353:21:1;;;5390:18;;;5383:30;-1:-1:-1;;;;;;;;;;;5429:18:1;;;5422:62;5501:18;;25220:68:0;5169:356:1;25220:68:0;35725:58:::1;-1:-1:-1::0;;;;;35725:33:0;::::1;35759:10;35771:11:::0;35725:33:::1;:58::i;:::-;35799:36;::::0;;-1:-1:-1;;;;;7207:55:1;;7189:74;;7294:2;7279:18;;7272:34;;;35799:36:0::1;::::0;7162:18:1;35799:36:0::1;7015:297:1::0;34319:165:0;25081:6;;-1:-1:-1;;;;;25081:6:0;21482:10;25228:23;25220:68;;;;-1:-1:-1;;;25220:68:0;;5371:2:1;25220:68:0;;;5353:21:1;;;5390:18;;;5383:30;-1:-1:-1;;;;;;;;;;;5429:18:1;;;5422:62;5501:18;;25220:68:0;5169:356:1;27405:34:0;;;;;;;;;;;;37406:408;25081:6;;-1:-1:-1;;;;;25081:6:0;21482:10;25228:23;25220:68;;;;-1:-1:-1;;;25220:68:0;;5371:2:1;25220:68:0;;;5353:21:1;;;5390:18;;;5383:30;-1:-1:-1;;;;;;;;;;;5429:18:1;;;5422:62;5501:18;;25220:68:0;5169:356:1;25220:68:0;37517:12:::1;-1:-1:-1::0;;;;;37492:38:0::1;:13;-1:-1:-1::0;;;;;37492:38:0::1;::::0;37484:108:::1;;;::::0;-1:-1:-1;;;37484:108:0;;7519:2:1;37484:108:0::1;::::0;::::1;7501:21:1::0;7558:2;7538:18;;;7531:30;7597:34;7577:18;;;7570:62;7668:27;7648:18;;;7641:55;7713:19;;37484:108:0::1;7317:421:1::0;37484:108:0::1;37636:12;-1:-1:-1::0;;;;;37611:38:0::1;:13;-1:-1:-1::0;;;;;37611:38:0::1;::::0;37603:109:::1;;;::::0;-1:-1:-1;;;37603:109:0;;7945:2:1;37603:109:0::1;::::0;::::1;7927:21:1::0;7984:2;7964:18;;;7957:30;8023:34;8003:18;;;7996:62;8094:28;8074:18;;;8067:56;8140:19;;37603:109:0::1;7743:422:1::0;37603:109:0::1;37723:12;:36:::0;;-1:-1:-1;;37723:36:0::1;-1:-1:-1::0;;;;;37723:36:0;::::1;::::0;;::::1;::::0;;;37775:31:::1;::::0;933:74:1;;;37775:31:0::1;::::0;921:2:1;906:18;37775:31:0::1;773:240:1::0;30497:359:0;30574:7;;30594:236;30613:11;:18;30609:22;;30594:236;;;30701:11;30713:1;30701:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;30675:23:0;;;;:14;:23;;;;;;;;30657:41;;:15;:41;:::i;:::-;:58;30653:166;;;30785:18;;30762:17;30780:1;30762:20;;;;;;;;:::i;:::-;;;;;;;;;30743:16;:39;;;;:::i;:::-;:60;;;;:::i;:::-;30736:67;;;;;30653:166;30633:3;;;:::i;:::-;;;30594:236;;;-1:-1:-1;30847:1:0;;30497:359;-1:-1:-1;;;30497:359:0:o;30918:432::-;18467:1;19065:7;;:19;19057:63;;;;-1:-1:-1;;;19057:63:0;;6354:2:1;19057:63:0;;;6336:21:1;6393:2;6373:18;;;6366:30;6432:33;6412:18;;;6405:61;6483:18;;19057:63:0;6152:355:1;19057:63:0;18467:1;19198:7;:18;22825:7;;-1:-1:-1;;;22825:7:0;;;;23079:9:::1;23071:38;;;::::0;-1:-1:-1;;;23071:38:0;;8701:2:1;23071:38:0::1;::::0;::::1;8683:21:1::0;8740:2;8720:18;;;8713:30;-1:-1:-1;;;8759:18:1;;;8752:46;8815:18;;23071:38:0::1;8499:340:1::0;23071:38:0::1;30998:10:::2;41516:16;:14;:16::i;:::-;41493:20;:39:::0;41573:23:::2;:21;:23::i;:::-;41543:27;:53:::0;41624:26:::2;:24;:26::i;:::-;41607:14;:43:::0;-1:-1:-1;;;;;41665:21:0;::::2;::::0;41661:303:::2;;41722:15;41729:7;41722:6;:15::i;:::-;-1:-1:-1::0;;;;;41703:16:0;::::2;;::::0;;;:7:::2;:16;::::0;;;;;;;:34;;;;41786:20:::2;::::0;41752:22:::2;:31:::0;;;;;;:54;41847:22:::2;41711:7:::0;41847:13:::2;:22::i;:::-;-1:-1:-1::0;;;;;41821:23:0;::::2;;::::0;;;:14:::2;:23;::::0;;;;;;;:48;;;;41925:27:::2;::::0;41884:29:::2;:38:::0;;;;;;:68;41661:303:::2;31038:1:::3;31029:6;:10;31021:37;;;::::0;-1:-1:-1;;;31021:37:0;;9046:2:1;31021:37:0::3;::::0;::::3;9028:21:1::0;9085:2;9065:18;;;9058:30;9124:16;9104:18;;;9097:44;9158:18;;31021:37:0::3;8844:338:1::0;31021:37:0::3;31099:6;31084:12;;:21;;;;:::i;:::-;31069:12;:36:::0;31150:10:::3;31140:21;::::0;;;:9:::3;:21;::::0;;;;;:30:::3;::::0;31164:6;;31140:30:::3;:::i;:::-;31126:10;31116:21;::::0;;;:9:::3;:21;::::0;;;;;;;:54;;;;31181:14:::3;:26:::0;;;;;;31210:15:::3;31181:44:::0;;31236:64:::3;::::0;:12:::3;-1:-1:-1::0;;;;;31236:29:0::3;::::0;31286:4:::3;31293:6:::0;31236:29:::3;:64::i;:::-;31316:26;::::0;552:25:1;;;31323:10:0::3;::::0;31316:26:::3;::::0;540:2:1;525:18;31316:26:0::3;406:177:1::0;37080:292:0;25081:6;;-1:-1:-1;;;;;25081:6:0;21482:10;25228:23;25220:68;;;;-1:-1:-1;;;25220:68:0;;5371:2:1;25220:68:0;;;5353:21:1;;;5390:18;;;5383:30;-1:-1:-1;;;;;;;;;;;5429:18:1;;;5422:62;5501:18;;25220:68:0;5169:356:1;25220:68:0;37196:12:::1;;37178:15;:30;37156:168;;;::::0;-1:-1:-1;;;37156:168:0;;9389:2:1;37156:168:0::1;::::0;::::1;9371:21:1::0;9428:2;9408:18;;;9401:30;9467:34;9447:18;;;9440:62;9538:34;9518:18;;;9511:62;9610:26;9589:19;;;9582:55;9654:19;;37156:168:0::1;9187:492:1::0;37156:168:0::1;37335:29;37355:8;37335:19;:29::i;:::-;37080:292:::0;:::o;29078:285::-;29125:7;29149:12;;29165:1;29149:17;29145:77;;-1:-1:-1;29190:20:0;;;29078:285::o;29145:77::-;29343:12;;29323:10;;29305:14;;29276:26;:24;:26::i;:::-;:43;;;;:::i;:::-;29275:58;;;;:::i;:::-;:65;;29336:4;29275:65;:::i;:::-;:80;;;;:::i;:::-;29252:20;;:103;;;;:::i;36853:219::-;25081:6;;-1:-1:-1;;;;;25081:6:0;21482:10;25228:23;25220:68;;;;-1:-1:-1;;;25220:68:0;;5371:2:1;25220:68:0;;;5353:21:1;;;5390:18;;;5383:30;-1:-1:-1;;;;;;;;;;;5429:18:1;;;5422:62;5501:18;;25220:68:0;5169:356:1;25220:68:0;36929:9:::1;::::0;;36906:20:::1;36949:13:::0;;;36973:48:::1;36999:7;25081:6:::0;;-1:-1:-1;;;;;25081:6:0;;25008:87;36999:7:::1;-1:-1:-1::0;;;;;36973:12:0::1;:25;::::0;37008:12;36973:25:::1;:48::i;:::-;37037:27;::::0;552:25:1;;;37037:27:0::1;::::0;540:2:1;525:18;37037:27:0::1;406:177:1::0;33700:126:0;33755:10;33745:21;;;;:9;:21;;;;;;33736:31;;:8;:31::i;:::-;33778:11;:9;:11::i;:::-;33800:18;:16;:18::i;31358:617::-;18467:1;19065:7;;:19;19057:63;;;;-1:-1:-1;;;19057:63:0;;6354:2:1;19057:63:0;;;6336:21:1;6393:2;6373:18;;;6366:30;6432:33;6412:18;;;6405:61;6483:18;;19057:63:0;6152:355:1;19057:63:0;18467:1;19198:7;:18;22825:7;;-1:-1:-1;;;22825:7:0;;;;23079:9:::1;23071:38;;;::::0;-1:-1:-1;;;23071:38:0;;8701:2:1;23071:38:0::1;::::0;::::1;8683:21:1::0;8740:2;8720:18;;;8713:30;-1:-1:-1;;;8759:18:1;;;8752:46;8815:18;;23071:38:0::1;8499:340:1::0;23071:38:0::1;31494:10:::2;41516:16;:14;:16::i;:::-;41493:20;:39:::0;41573:23:::2;:21;:23::i;:::-;41543:27;:53:::0;41624:26:::2;:24;:26::i;:::-;41607:14;:43:::0;-1:-1:-1;;;;;41665:21:0;::::2;::::0;41661:303:::2;;41722:15;41729:7;41722:6;:15::i;:::-;-1:-1:-1::0;;;;;41703:16:0;::::2;;::::0;;;:7:::2;:16;::::0;;;;;;;:34;;;;41786:20:::2;::::0;41752:22:::2;:31:::0;;;;;;:54;41847:22:::2;41711:7:::0;41847:13:::2;:22::i;:::-;-1:-1:-1::0;;;;;41821:23:0;::::2;;::::0;;;:14:::2;:23;::::0;;;;;;;:48;;;;41925:27:::2;::::0;41884:29:::2;:38:::0;;;;;;:68;41661:303:::2;31534:1:::3;31525:6;:10;31517:37;;;::::0;-1:-1:-1;;;31517:37:0;;9046:2:1;31517:37:0::3;::::0;::::3;9028:21:1::0;9085:2;9065:18;;;9058:30;9124:16;9104:18;;;9097:44;9158:18;;31517:37:0::3;8844:338:1::0;31517:37:0::3;31595:6;31580:12;;:21;;;;:::i;:::-;31565:12;:36:::0;31646:10:::3;31636:21;::::0;;;:9:::3;:21;::::0;;;;;:30:::3;::::0;31660:6;;31636:30:::3;:::i;:::-;31622:10;31612:21;::::0;;;:9:::3;:21;::::0;;;;;;:54;;;;31698:93;;;;;::::3;::::0;::::3;10056:34:1::0;;;;31758:4:0::3;10106:18:1::0;;;10099:43;10158:18;;;10151:34;;;10201:18;;;10194:34;;;10277:4;10265:17;;10244:19;;;10237:46;10299:19;;;10292:35;;;10343:19;;;10336:35;;;-1:-1:-1;;;;;31716:12:0::3;31698:39;::::0;::::3;::::0;9967:19:1;;31698:93:0::3;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;-1:-1:-1::0;;31819:10:0::3;31804:26;::::0;;;:14:::3;:26;::::0;;;;31833:15:::3;31804:44:::0;;31861:64:::3;::::0;-1:-1:-1;31861:12:0::3;-1:-1:-1::0;;;;;31861:29:0::3;::::0;-1:-1:-1;31911:4:0::3;31918:6:::0;31861:29:::3;:64::i;:::-;31941:26;::::0;552:25:1;;;31948:10:0::3;::::0;31941:26:::3;::::0;540:2:1;525:18;31941:26:0::3;;;;;;;-1:-1:-1::0;;18423:1:0;19377:7;:22;-1:-1:-1;;;;31358:617:0:o;25917:201::-;25081:6;;-1:-1:-1;;;;;25081:6:0;21482:10;25228:23;25220:68;;;;-1:-1:-1;;;25220:68:0;;5371:2:1;25220:68:0;;;5353:21:1;;;5390:18;;;5383:30;-1:-1:-1;;;;;;;;;;;5429:18:1;;;5422:62;5501:18;;25220:68:0;5169:356:1;25220:68:0;-1:-1:-1;;;;;26006:22:0;::::1;25998:73;;;::::0;-1:-1:-1;;;25998:73:0;;10584:2:1;25998:73:0::1;::::0;::::1;10566:21:1::0;10623:2;10603:18;;;10596:30;10662:34;10642:18;;;10635:62;10733:8;10713:18;;;10706:36;10759:19;;25998:73:0::1;10382:402:1::0;25998:73:0::1;26082:28;26101:8;26082:18;:28::i;30225:132::-:0;30287:7;30334:15;;30314:17;;:35;;;;:::i;36320:525::-;25081:6;;-1:-1:-1;;;;;25081:6:0;21482:10;25228:23;25220:68;;;;-1:-1:-1;;;25220:68:0;;5371:2:1;25220:68:0;;;5353:21:1;;;5390:18;;;5383:30;-1:-1:-1;;;;;;;;;;;5429:18:1;;;5422:62;5501:18;;25220:68:0;5169:356:1;25220:68:0;36400:12:::1;::::0;-1:-1:-1;;;;;36400:12:0::1;36384:113;;;::::0;-1:-1:-1;;;36384:113:0;;10991:2:1;36384:113:0::1;::::0;::::1;10973:21:1::0;11030:2;11010:18;;;11003:30;11069:34;11049:18;;;11042:62;11140:34;11120:18;;;11113:62;11212:3;11191:19;;;11184:32;11233:19;;36384:113:0::1;10789:469:1::0;36384:113:0::1;36516:12;::::0;:17;36508:94:::1;;;::::0;;-1:-1:-1;;;36508:94:0;;11465:2:1;36508:94:0::1;::::0;::::1;11447:21:1::0;11484:18;;;11477:30;;;;11543:34;11523:18;;;11516:62;11614:34;11594:18;;;11587:62;11666:19;;36508:94:0::1;11263:428:1::0;36508:94:0::1;36636:12;::::0;:37:::1;::::0;-1:-1:-1;;;36636:37:0;;36667:4:::1;36636:37;::::0;::::1;933:74:1::0;36613:20:0::1;::::0;-1:-1:-1;;;;;36636:12:0::1;::::0;:22:::1;::::0;906:18:1;;36636:37:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;36613:60:::0;-1:-1:-1;36688:16:0;;36684:100:::1;;36721:12;::::0;:51:::1;::::0;-1:-1:-1;;;;;36721:12:0::1;36747:10;36759:12:::0;36721:25:::1;:51::i;:::-;36799:38;::::0;552:25:1;;;36799:38:0::1;::::0;540:2:1;525:18;36799:38:0::1;406:177:1::0;13353:211:0;13497:58;;-1:-1:-1;;;;;7207:55:1;;13497:58:0;;;7189:74:1;7279:18;;;7272:34;;;13470:86:0;;13490:5;;13520:23;;7162:18:1;;13497:58:0;;;;-1:-1:-1;;13497:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;13470:19;:86::i;32215:732::-;32286:1;32277:6;:10;32269:40;;;;-1:-1:-1;;;32269:40:0;;11898:2:1;32269:40:0;;;11880:21:1;11937:2;11917:18;;;11910:30;11976:19;11956:18;;;11949:47;12013:18;;32269:40:0;11696:341:1;32269:40:0;32348:10;32320:15;32338:21;;;:9;:21;;;;;;32378:17;;;;32370:71;;;;-1:-1:-1;;;32370:71:0;;12244:2:1;32370:71:0;;;12226:21:1;12283:2;12263:18;;;12256:30;12322:34;12302:18;;;12295:62;12393:11;12373:18;;;12366:39;12422:19;;32370:71:0;12042:405:1;32370:71:0;32482:6;32467:12;;:21;;;;:::i;:::-;32452:12;:36;32499:20;32522:23;32526:10;32538:6;32522:3;:23::i;:::-;32499:46;-1:-1:-1;32580:16:0;32590:6;32580:7;:16;:::i;:::-;32566:10;32556:21;;;;:9;:21;;;;;:40;;;;32637:21;32646:12;32637:6;:21;:::i;:::-;32607:51;-1:-1:-1;32669:58:0;-1:-1:-1;;;;;32669:12:0;:25;32695:10;32607:51;32669:25;:58::i;:::-;32743:42;;552:25:1;;;32753:10:0;;32743:42;;540:2:1;525:18;32743:42:0;;;;;;;32800:16;;32796:144;;32838:39;;552:25:1;;;32852:10:0;;32838:39;;540:2:1;525:18;32838:39:0;;;;;;;32916:12;32904:9;;:24;;;;:::i;:::-;32892:9;:36;32796:144;32258:689;;;32215:732;:::o;23813:120::-;22825:7;;-1:-1:-1;;;22825:7:0;;;;23349:41;;;;-1:-1:-1;;;23349:41:0;;12654:2:1;23349:41:0;;;12636:21:1;12693:2;12673:18;;;12666:30;12732:22;12712:18;;;12705:50;12772:18;;23349:41:0;12452:344:1;23349:41:0;23872:7:::1;:15:::0;;-1:-1:-1;;;;23872:15:0::1;::::0;;23903:22:::1;21482:10:::0;23912:12:::1;23903:22;::::0;-1:-1:-1;;;;;951:55:1;;;933:74;;921:2;906:18;23903:22:0::1;;;;;;;23813:120::o:0;26278:191::-;26371:6;;;-1:-1:-1;;;;;26388:17:0;;;-1:-1:-1;;26388:17:0;;;;;;;26421:40;;26371:6;;;26388:17;26371:6;;26421:40;;26352:16;;26421:40;26341:128;26278:191;:::o;38372:1010::-;38518:18;:25;38495:12;:19;:48;38487:125;;;;;-1:-1:-1;;;38487:125:0;;13003:2:1;38487:125:0;;;12985:21:1;13022:18;;;13015:30;;;;13081:34;13061:18;;;13054:62;13152:34;13132:18;;;13125:62;13204:19;;38487:125:0;12801:428:1;38487:125:0;38654:2;38631:12;:19;:25;;38623:111;;;;-1:-1:-1;;;38623:111:0;;13436:2:1;38623:111:0;;;13418:21:1;13475:2;13455:18;;;13448:30;13514:34;13494:18;;;13487:62;13585:34;13565:18;;;13558:62;13657:11;13636:19;;;13629:40;13686:19;;38623:111:0;13234:477:1;38623:111:0;38745:23;38783:25;38811:16;;38830:1;38811:20;;;;:::i;:::-;38783:48;;38846:9;38842:380;38865:12;:19;38861:1;:23;38842:380;;;38931:15;38913:12;38926:1;38913:15;;;;;;;;:::i;:::-;;;;;;;:33;38905:77;;;;-1:-1:-1;;;38905:77:0;;13918:2:1;38905:77:0;;;13900:21:1;13957:2;13937:18;;;13930:30;13996:33;13976:18;;;13969:61;14047:18;;38905:77:0;13716:355:1;38905:77:0;39028:17;39004:18;39023:1;39004:21;;;;;;;;:::i;:::-;;;;;;;:41;38996:112;;;;-1:-1:-1;;;38996:112:0;;14278:2:1;38996:112:0;;;14260:21:1;14317:2;14297:18;;;14290:30;14356:34;14336:18;;;14329:62;14427:28;14407:18;;;14400:56;14473:19;;38996:112:0;14076:422:1;38996:112:0;39140:12;39153:1;39140:15;;;;;;;;:::i;:::-;;;;;;;39122:33;;39189:18;39208:1;39189:21;;;;;;;;:::i;:::-;;;;;;;39169:41;;38886:3;;;;:::i;:::-;;;38842:380;;;-1:-1:-1;39232:26:0;;;;:11;;:26;;;;;:::i;:::-;-1:-1:-1;39269:38:0;;;;:17;;:38;;;;;:::i;:::-;;39323:51;39341:12;39355:18;39323:51;;;;;;;:::i;:::-;;;;;;;;38476:906;;38372:1010;;:::o;13572:248::-;13743:68;;-1:-1:-1;;;;;15694:15:1;;;13743:68:0;;;15676:34:1;15746:15;;15726:18;;;15719:43;15778:18;;;15771:34;;;13716:96:0;;13736:5;;13766:27;;15588:18:1;;13743:68:0;15413:398:1;39436:1954:0;39546:1;41516:16;:14;:16::i;:::-;41493:20;:39;41573:23;:21;:23::i;:::-;41543:27;:53;41624:26;:24;:26::i;:::-;41607:14;:43;-1:-1:-1;;;;;41665:21:0;;;41661:303;;41722:15;41729:7;41722:6;:15::i;:::-;-1:-1:-1;;;;;41703:16:0;;;;;;:7;:16;;;;;;;;:34;;;;41786:20;;41752:22;:31;;;;;;:54;41847:22;41711:7;41847:13;:22::i;:::-;-1:-1:-1;;;;;41821:23:0;;;;;;:14;:23;;;;;;;;:48;;;;41925:27;;41884:29;:38;;;;;;:68;41661:303;39565:12;;39561:74:::1;;39594:29;39614:8;39594:19;:29::i;:::-;39670:12;;39651:15;:31;39647:527;;39721:15;::::0;39712:24:::1;::::0;:6;:24:::1;:::i;:::-;39699:10;:37:::0;39787:15:::1;::::0;39771:31:::1;::::0;:13;:31:::1;:::i;:::-;39751:17;:51:::0;39647:527:::1;;;39835:17;39870:15;39855:12;;:30;;;;:::i;:::-;39835:50;;39900:16;39931:10;;39919:9;:22;;;;:::i;:::-;39991:15;::::0;39900:41;;-1:-1:-1;39970:17:0::1;39900:41:::0;39970:6;:17:::1;:::i;:::-;39969:37;;;;:::i;:::-;39956:10;:50:::0;40059:17:::1;::::0;40021:23:::1;::::0;40047:29:::1;::::0;:9;:29:::1;:::i;:::-;40147:15;::::0;40021:55;;-1:-1:-1;40112:31:0::1;40021:55:::0;40112:13;:31:::1;:::i;:::-;40111:51;;;;:::i;:::-;40091:17;:71:::0;-1:-1:-1;;;39647:527:0::1;40549:37;::::0;-1:-1:-1;;;40549:37:0;;40580:4:::1;40549:37;::::0;::::1;933:74:1::0;40534:12:0::1;::::0;40549::::1;-1:-1:-1::0;;;;;40549:22:0::1;::::0;::::1;::::0;906:18:1;;40549:37:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;40534:52;;40617:12;-1:-1:-1::0;;;;;40601:28:0::1;:12;-1:-1:-1::0;;;;;40601:28:0::1;;40597:357;;40678:15;::::0;40668:25:::1;::::0;:7;:25:::1;:::i;:::-;40654:10;;:39;;40646:76;;;::::0;-1:-1:-1;;;40646:76:0;;16018:2:1;40646:76:0::1;::::0;::::1;16000:21:1::0;16057:2;16037:18;;;16030:30;16096:26;16076:18;;;16069:54;16140:18;;40646:76:0::1;15816:348:1::0;40646:76:0::1;40597:357;;;40898:15;::::0;40882:12:::1;::::0;40872:22:::1;::::0;:7;:22:::1;:::i;:::-;40871:42;;;;:::i;:::-;40857:10;;:56;;40849:93;;;::::0;-1:-1:-1;;;40849:93:0;;16018:2:1;40849:93:0::1;::::0;::::1;16000:21:1::0;16057:2;16037:18;;;16030:30;16096:26;16076:18;;;16069:54;16140:18;;40849:93:0::1;15816:348:1::0;40849:93:0::1;40978:12;::::0;-1:-1:-1;;;;;40978:12:0::1;40970:35:::0;40966:240:::1;;41044:12;::::0;:37:::1;::::0;-1:-1:-1;;;41044:37:0;;41075:4:::1;41044:37;::::0;::::1;933:74:1::0;41022:19:0::1;::::0;-1:-1:-1;;;;;41044:12:0::1;::::0;:22:::1;::::0;906:18:1;;41044:37:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41022:59;;41142:15;;41125:14;:32;;;;:::i;:::-;41104:17;;:53;;41096:98;;;::::0;-1:-1:-1;;;41096:98:0;;16371:2:1;41096:98:0::1;::::0;::::1;16353:21:1::0;;;16390:18;;;16383:30;16449:34;16429:18;;;16422:62;16501:18;;41096:98:0::1;16169:356:1::0;41096:98:0::1;41007:199;40966:240;41235:15;41218:14;:32:::0;;;41294:15:::1;::::0;41276:33:::1;::::0;::::1;:::i;:::-;41261:12;:48:::0;41327:55:::1;::::0;;16732:25:1;;;16788:2;16773:18;;16766:34;;;16816:18;;;16809:34;;;41327:55:0::1;::::0;16720:2:1;16705:18;41327:55:0::1;;;;;;;39550:1840;39436:1954:::0;;;;:::o;19925:106::-;19983:7;20014:1;20010;:5;:13;;20022:1;20010:13;;;20018:1;20010:13;20003:20;19925:106;-1:-1:-1;;;19925:106:0:o;23554:118::-;22825:7;;-1:-1:-1;;;22825:7:0;;;;23079:9;23071:38;;;;-1:-1:-1;;;23071:38:0;;8701:2:1;23071:38:0;;;8683:21:1;8740:2;8720:18;;;8713:30;-1:-1:-1;;;8759:18:1;;;8752:46;8815:18;;23071:38:0;8499:340:1;23071:38:0;23624:4:::1;23614:14:::0;;-1:-1:-1;;;;23614:14:0::1;-1:-1:-1::0;;;23614:14:0::1;::::0;;23644:20:::1;23651:12;21482:10:::0;;21402:98;38209:155;38275:15;:26;;;38317:39;;552:25:1;;;38317:39:0;;540:2:1;525:18;38317:39:0;406:177:1;15926:716:0;16350:23;16376:69;16404:4;16376:69;;;;;;;;;;;;;;;;;16384:5;-1:-1:-1;;;;;16376:27:0;;;:69;;;;;:::i;:::-;16460:17;;16350:95;;-1:-1:-1;16460:21:0;16456:179;;16557:10;16546:30;;;;;;;;;;;;:::i;:::-;16538:85;;;;-1:-1:-1;;;16538:85:0;;17338:2:1;16538:85:0;;;17320:21:1;17377:2;17357:18;;;17350:30;17416:34;17396:18;;;17389:62;17487:12;17467:18;;;17460:40;17517:19;;16538:85:0;17136:406:1;5240:229:0;5377:12;5409:52;5431:6;5439:4;5445:1;5448:12;5409:21;:52::i;:::-;5402:59;5240:229;-1:-1:-1;;;;5240:229:0:o;6360:510::-;6530:12;6588:5;6563:21;:30;;6555:81;;;;-1:-1:-1;;;6555:81:0;;17749:2:1;6555:81:0;;;17731:21:1;17788:2;17768:18;;;17761:30;17827:34;17807:18;;;17800:62;17898:8;17878:18;;;17871:36;17924:19;;6555:81:0;17547:402:1;6555:81:0;-1:-1:-1;;;;;2790:19:0;;;6647:60;;;;-1:-1:-1;;;6647:60:0;;18156:2:1;6647:60:0;;;18138:21:1;18195:2;18175:18;;;18168:30;18234:31;18214:18;;;18207:59;18283:18;;6647:60:0;17954:353:1;6647:60:0;6721:12;6735:23;6762:6;-1:-1:-1;;;;;6762:11:0;6781:5;6788:4;6762:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6720:73;;;;6811:51;6828:7;6837:10;6849:12;6811:16;:51::i;:::-;6804:58;6360:510;-1:-1:-1;;;;;;;6360:510:0:o;9046:712::-;9196:12;9225:7;9221:530;;;-1:-1:-1;9256:10:0;9249:17;;9221:530;9370:17;;:21;9366:374;;9568:10;9562:17;9629:15;9616:10;9612:2;9608:19;9601:44;9366:374;9711:12;9704:20;;-1:-1:-1;;;9704:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:196:1;82:20;;-1:-1:-1;;;;;131:54:1;;121:65;;111:93;;200:1;197;190:12;111:93;14:196;;;:::o;215:186::-;274:6;327:2;315:9;306:7;302:23;298:32;295:52;;;343:1;340;333:12;295:52;366:29;385:9;366:29;:::i;588:180::-;647:6;700:2;688:9;679:7;675:23;671:32;668:52;;;716:1;713;706:12;668:52;-1:-1:-1;739:23:1;;588:180;-1:-1:-1;588:180:1:o;1210:184::-;-1:-1:-1;;;1259:1:1;1252:88;1359:4;1356:1;1349:15;1383:4;1380:1;1373:15;1399:902;1453:5;1506:3;1499:4;1491:6;1487:17;1483:27;1473:55;;1524:1;1521;1514:12;1473:55;1560:6;1547:20;1586:4;1609:18;1646:2;1642;1639:10;1636:36;;;1652:18;;:::i;:::-;1698:2;1695:1;1691:10;1730:2;1724:9;1793:2;1789:7;1784:2;1780;1776:11;1772:25;1764:6;1760:38;1848:6;1836:10;1833:22;1828:2;1816:10;1813:18;1810:46;1807:72;;;1859:18;;:::i;:::-;1895:2;1888:22;1945:18;;;2021:15;;;2017:24;;;1979:15;;;;-1:-1:-1;2053:15:1;;;2050:35;;;2081:1;2078;2071:12;2050:35;2117:2;2109:6;2105:15;2094:26;;2129:142;2145:6;2140:3;2137:15;2129:142;;;2211:17;;2199:30;;2249:12;;;;2162;;;;2129:142;;2306:595;2424:6;2432;2485:2;2473:9;2464:7;2460:23;2456:32;2453:52;;;2501:1;2498;2491:12;2453:52;2541:9;2528:23;2570:18;2611:2;2603:6;2600:14;2597:34;;;2627:1;2624;2617:12;2597:34;2650:61;2703:7;2694:6;2683:9;2679:22;2650:61;:::i;:::-;2640:71;;2764:2;2753:9;2749:18;2736:32;2720:48;;2793:2;2783:8;2780:16;2777:36;;;2809:1;2806;2799:12;2777:36;;2832:63;2887:7;2876:8;2865:9;2861:24;2832:63;:::i;:::-;2822:73;;;2306:595;;;;;:::o;2906:316::-;2983:6;2991;2999;3052:2;3040:9;3031:7;3027:23;3023:32;3020:52;;;3068:1;3065;3058:12;3020:52;-1:-1:-1;;3091:23:1;;;3161:2;3146:18;;3133:32;;-1:-1:-1;3212:2:1;3197:18;;;3184:32;;2906:316;-1:-1:-1;2906:316:1:o;3227:254::-;3295:6;3303;3356:2;3344:9;3335:7;3331:23;3327:32;3324:52;;;3372:1;3369;3362:12;3324:52;3395:29;3414:9;3395:29;:::i;:::-;3385:39;3471:2;3456:18;;;;3443:32;;-1:-1:-1;;;3227:254:1:o;3717:543::-;3810:6;3818;3826;3834;3842;3895:3;3883:9;3874:7;3870:23;3866:33;3863:53;;;3912:1;3909;3902:12;3863:53;3948:9;3935:23;3925:33;;4005:2;3994:9;3990:18;3977:32;3967:42;;4059:2;4048:9;4044:18;4031:32;4103:4;4096:5;4092:16;4085:5;4082:27;4072:55;;4123:1;4120;4113:12;4072:55;3717:543;;;;-1:-1:-1;4146:5:1;;4198:2;4183:18;;4170:32;;-1:-1:-1;4249:3:1;4234:19;4221:33;;3717:543;-1:-1:-1;;3717:543:1:o;4265:184::-;-1:-1:-1;;;4314:1:1;4307:88;4414:4;4411:1;4404:15;4438:4;4435:1;4428:15;4454:125;4494:4;4522:1;4519;4516:8;4513:34;;;4527:18;;:::i;:::-;-1:-1:-1;4564:9:1;;4454:125::o;4584:168::-;4624:7;4690:1;4686;4682:6;4678:14;4675:1;4672:21;4667:1;4660:9;4653:17;4649:45;4646:71;;;4697:18;;:::i;:::-;-1:-1:-1;4737:9:1;;4584:168::o;4757:274::-;4797:1;4823;4813:189;;-1:-1:-1;;;4855:1:1;4848:88;4959:4;4956:1;4949:15;4987:4;4984:1;4977:15;4813:189;-1:-1:-1;5016:9:1;;4757:274::o;5036:128::-;5076:3;5107:1;5103:6;5100:1;5097:13;5094:39;;;5113:18;;:::i;:::-;-1:-1:-1;5149:9:1;;5036:128::o;5963:184::-;6033:6;6086:2;6074:9;6065:7;6061:23;6057:32;6054:52;;;6102:1;6099;6092:12;6054:52;-1:-1:-1;6125:16:1;;5963:184;-1:-1:-1;5963:184:1:o;8170:::-;-1:-1:-1;;;8219:1:1;8212:88;8319:4;8316:1;8309:15;8343:4;8340:1;8333:15;8359:135;8398:3;8419:17;;;8416:43;;8439:18;;:::i;:::-;-1:-1:-1;8486:1:1;8475:13;;8359:135::o;14503:435::-;14556:3;14594:5;14588:12;14621:6;14616:3;14609:19;14647:4;14676:2;14671:3;14667:12;14660:19;;14713:2;14706:5;14702:14;14734:1;14744:169;14758:6;14755:1;14752:13;14744:169;;;14819:13;;14807:26;;14853:12;;;;14888:15;;;;14780:1;14773:9;14744:169;;;-1:-1:-1;14929:3:1;;14503:435;-1:-1:-1;;;;;14503:435:1:o;14943:465::-;15200:2;15189:9;15182:21;15163:4;15226:56;15278:2;15267:9;15263:18;15255:6;15226:56;:::i;:::-;15330:9;15322:6;15318:22;15313:2;15302:9;15298:18;15291:50;15358:44;15395:6;15387;15358:44;:::i;:::-;15350:52;14943:465;-1:-1:-1;;;;;14943:465:1:o;16854:277::-;16921:6;16974:2;16962:9;16953:7;16949:23;16945:32;16942:52;;;16990:1;16987;16980:12;16942:52;17022:9;17016:16;17075:5;17068:13;17061:21;17054:5;17051:32;17041:60;;17097:1;17094;17087:12;18312:258;18384:1;18394:113;18408:6;18405:1;18402:13;18394:113;;;18484:11;;;18478:18;18465:11;;;18458:39;18430:2;18423:10;18394:113;;;18525:6;18522:1;18519:13;18516:48;;;-1:-1:-1;;18560:1:1;18542:16;;18535:27;18312:258::o;18575:274::-;18704:3;18742:6;18736:13;18758:53;18804:6;18799:3;18792:4;18784:6;18780:17;18758:53;:::i;:::-;18827:16;;;;;18575:274;-1:-1:-1;;18575:274:1:o;18854:383::-;19003:2;18992:9;18985:21;18966:4;19035:6;19029:13;19078:6;19073:2;19062:9;19058:18;19051:34;19094:66;19153:6;19148:2;19137:9;19133:18;19128:2;19120:6;19116:15;19094:66;:::i;:::-;19221:2;19200:15;-1:-1:-1;;19196:29:1;19181:45;;;;19228:2;19177:54;;18854:383;-1:-1:-1;;18854:383:1:o
Swarm Source
ipfs://f1782956c14f05a3ad891819b987778508dbc25a816f61f86c1be51a059aafaa
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.