More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 58 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Get Reward | 21815026 | 23 days ago | IN | 0 ETH | 0.00030121 | ||||
Sync | 20602158 | 193 days ago | IN | 0 ETH | 0.00024097 | ||||
Sync | 20530597 | 203 days ago | IN | 0 ETH | 0.00028902 | ||||
Get Reward | 20254226 | 241 days ago | IN | 0 ETH | 0.00065724 | ||||
Sync | 19756416 | 311 days ago | IN | 0 ETH | 0.00142473 | ||||
Get Reward | 19651862 | 325 days ago | IN | 0 ETH | 0.00425842 | ||||
Sync | 19073449 | 406 days ago | IN | 0 ETH | 0.00217234 | ||||
Get Reward | 18671770 | 463 days ago | IN | 0 ETH | 0.01958159 | ||||
Sync | 18671766 | 463 days ago | IN | 0 ETH | 0.00872209 | ||||
Withdraw Locked | 18442166 | 495 days ago | IN | 0 ETH | 0.0126072 | ||||
Get Reward | 18384612 | 503 days ago | IN | 0 ETH | 0.00474595 | ||||
Get Reward | 18251001 | 522 days ago | IN | 0 ETH | 0.00449779 | ||||
Get Reward | 18250999 | 522 days ago | IN | 0 ETH | 0.00448912 | ||||
Sync | 18114155 | 541 days ago | IN | 0 ETH | 0.00330496 | ||||
Get Reward | 18070597 | 547 days ago | IN | 0 ETH | 0.00558032 | ||||
Get Reward | 18070591 | 547 days ago | IN | 0 ETH | 0.00447758 | ||||
Stake Locked | 18070587 | 547 days ago | IN | 0 ETH | 0.0116127 | ||||
Sync | 17779711 | 588 days ago | IN | 0 ETH | 0.00492092 | ||||
Get Reward | 17479078 | 630 days ago | IN | 0 ETH | 0.00575754 | ||||
Withdraw Locked | 17479075 | 630 days ago | IN | 0 ETH | 0.0136381 | ||||
Sync | 17478709 | 630 days ago | IN | 0 ETH | 0.00270274 | ||||
Get Reward | 17377707 | 644 days ago | IN | 0 ETH | 0.00779156 | ||||
Get Reward | 17278157 | 658 days ago | IN | 0 ETH | 0.01522142 | ||||
Get Reward | 17273267 | 659 days ago | IN | 0 ETH | 0.0138195 | ||||
Withdraw Locked | 17273265 | 659 days ago | IN | 0 ETH | 0.03733809 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
FraxUnifiedFarm_ERC20_Convex_FRAXBP_Volatile
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-02-05 */ // SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.8.0; // Sources flattened with hardhat v2.12.5 https://hardhat.org // File contracts/Common/Context.sol /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return payable(msg.sender); } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } // File contracts/Math/SafeMath.sol /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. * * _Available since v2.4.0._ */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. * * _Available since v2.4.0._ */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. * * _Available since v2.4.0._ */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // File contracts/ERC20/IERC20.sol /** * @dev Interface of the ERC20 standard as defined in the EIP. Does not include * the optional functions; to access them see {ERC20Detailed}. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File contracts/Misc_AMOs/convex/IConvexStakingWrapperFrax.sol interface IConvexStakingWrapperFrax { function addRewards() external; function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function balanceOf(address account) external view returns (uint256); function collateralVault() external view returns (address); function convexBooster() external view returns (address); function convexPool() external view returns (address); function convexPoolId() external view returns (uint256); function convexToken() external view returns (address); function crv() external view returns (address); function curveToken() external view returns (address); function cvx() external view returns (address); function decimals() external view returns (uint8); function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool); function deposit(uint256 _amount, address _to) external; // function earned(address _account) external view returns (tuple[] memory claimable); function getReward(address _account, address _forwardTo) external; function getReward(address _account) external; function increaseAllowance(address spender, uint256 addedValue) external returns (bool); function initialize(address _curveToken, address _convexToken, address _convexPool, uint256 _poolId, address _vault) external; function isInit() external view returns (bool); function isShutdown() external view returns (bool); function name() external view returns (string memory); function owner() external view returns (address); function registeredRewards(address) external view returns (uint256); function renounceOwnership() external; function rewardLength() external view returns (uint256); function rewards(uint256) external view returns (address reward_token, address reward_pool, uint128 reward_integral, uint128 reward_remaining); function setApprovals() external; function setVault(address _vault) external; function shutdown() external; function stake(uint256 _amount, address _to) external; function symbol() external view returns (string memory); function totalBalanceOf(address _account) external view returns (uint256); function totalSupply() external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); function transferOwnership(address newOwner) external; function user_checkpoint(address _account) external returns (bool); function user_checkpoint(address[2] memory _accounts) external returns (bool); function withdraw(uint256 _amount) external; function withdrawAndUnwrap(uint256 _amount) external; } // File contracts/Misc_AMOs/convex/IDepositToken.sol interface IDepositToken { function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function balanceOf(address account) external view returns (uint256); function burn(address _from, uint256 _amount) external; function decimals() external view returns (uint8); function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool); function increaseAllowance(address spender, uint256 addedValue) external returns (bool); function mint(address _to, uint256 _amount) external; function name() external view returns (string memory); function operator() external view returns (address); function symbol() external view returns (string memory); function totalSupply() external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); } // File contracts/Misc_AMOs/curve/I2pool.sol interface I2pool { function decimals() external view returns (uint256); function transfer(address _to, uint256 _value) external returns (bool); function transferFrom(address _from, address _to, uint256 _value) external returns (bool); function approve(address _spender, uint256 _value) external returns (bool); function A() external view returns (uint256); function A_precise() external view returns (uint256); function get_virtual_price() external view returns (uint256); function lp_price() external view returns (uint256); function price_oracle() external view returns (uint256); function calc_token_amount(uint256[2] memory _amounts, bool _is_deposit) external view returns (uint256); function add_liquidity(uint256[2] memory _amounts, uint256 _min_mint_amount) external returns (uint256); function get_dy(int128 i, int128 j, uint256 _dx) external view returns (uint256); function exchange(int128 i, int128 j, uint256 _dx, uint256 _min_dy) external returns (uint256); function remove_liquidity(uint256 _amount, uint256[2] memory _min_amounts) external returns (uint256[2] memory); function remove_liquidity_imbalance(uint256[2] memory _amounts, uint256 _max_burn_amount) external returns (uint256); function calc_withdraw_one_coin(uint256 _token_amount, int128 i) external view returns (uint256); function remove_liquidity_one_coin(uint256 _token_amount, int128 i, uint256 _min_amount) external returns (uint256); function ramp_A(uint256 _future_A, uint256 _future_time) external; function stop_ramp_A() external; function commit_new_fee(uint256 _new_fee, uint256 _new_admin_fee) external; function apply_new_fee() external; function revert_new_parameters() external; function commit_transfer_ownership(address _owner) external; function apply_transfer_ownership() external; function revert_transfer_ownership() external; function admin_balances(uint256 i) external view returns (uint256); function withdraw_admin_fees() external; function donate_admin_fees() external; function kill_me() external; function unkill_me() external; function coins(uint256 arg0) external view returns (address); function balances(uint256 arg0) external view returns (uint256); function fee() external view returns (uint256); function admin_fee() external view returns (uint256); function owner() external view returns (address); function initial_A() external view returns (uint256); function future_A() external view returns (uint256); function initial_A_time() external view returns (uint256); function future_A_time() external view returns (uint256); function admin_actions_deadline() external view returns (uint256); function transfer_ownership_deadline() external view returns (uint256); function future_fee() external view returns (uint256); function future_admin_fee() external view returns (uint256); function future_owner() external view returns (address); function name() external view returns (string memory); function symbol() external view returns (string memory); function balanceOf(address arg0) external view returns (uint256); function allowance(address arg0, address arg1) external view returns (uint256); function totalSupply() external view returns (uint256); } // File contracts/Misc_AMOs/curve/I2poolToken.sol interface I2poolToken { function decimals() external view returns (uint256); function transfer(address _to, uint256 _value) external returns (bool); function transferFrom(address _from, address _to, uint256 _value) external returns (bool); function approve(address _spender, uint256 _value) external returns (bool); function increaseAllowance(address _spender, uint256 _added_value) external returns (bool); function decreaseAllowance(address _spender, uint256 _subtracted_value) external returns (bool); function mint(address _to, uint256 _value) external returns (bool); function burnFrom(address _to, uint256 _value) external returns (bool); function set_minter(address _minter) external; function set_name(string memory _name, string memory _symbol) external; function name() external view returns (string memory); function symbol() external view returns (string memory); function balanceOf(address arg0) external view returns (uint256); function allowance(address arg0, address arg1) external view returns (uint256); function totalSupply() external view returns (uint256); function minter() external view returns (address); } // File contracts/Curve/IFraxGaugeController.sol // https://github.com/swervefi/swerve/edit/master/packages/swerve-contracts/interfaces/IGaugeController.sol interface IFraxGaugeController { struct Point { uint256 bias; uint256 slope; } struct VotedSlope { uint256 slope; uint256 power; uint256 end; } // Public variables function admin() external view returns (address); function future_admin() external view returns (address); function token() external view returns (address); function voting_escrow() external view returns (address); function n_gauge_types() external view returns (int128); function n_gauges() external view returns (int128); function gauge_type_names(int128) external view returns (string memory); function gauges(uint256) external view returns (address); function vote_user_slopes(address, address) external view returns (VotedSlope memory); function vote_user_power(address) external view returns (uint256); function last_user_vote(address, address) external view returns (uint256); function points_weight(address, uint256) external view returns (Point memory); function time_weight(address) external view returns (uint256); function points_sum(int128, uint256) external view returns (Point memory); function time_sum(uint256) external view returns (uint256); function points_total(uint256) external view returns (uint256); function time_total() external view returns (uint256); function points_type_weight(int128, uint256) external view returns (uint256); function time_type_weight(uint256) external view returns (uint256); // Getter functions function gauge_types(address) external view returns (int128); function gauge_relative_weight(address) external view returns (uint256); function gauge_relative_weight(address, uint256) external view returns (uint256); function get_gauge_weight(address) external view returns (uint256); function get_type_weight(int128) external view returns (uint256); function get_total_weight() external view returns (uint256); function get_weights_sum_per_type(int128) external view returns (uint256); // External functions function commit_transfer_ownership(address) external; function apply_transfer_ownership() external; function add_gauge( address, int128, uint256 ) external; function checkpoint() external; function checkpoint_gauge(address) external; function global_emission_rate() external view returns (uint256); function gauge_relative_weight_write(address) external returns (uint256); function gauge_relative_weight_write(address, uint256) external returns (uint256); function add_type(string memory, uint256) external; function change_type_weight(int128, uint256) external; function change_gauge_weight(address, uint256) external; function change_global_emission_rate(uint256) external; function vote_for_gauge_weights(address, uint256) external; } // File contracts/Curve/IFraxGaugeFXSRewardsDistributor.sol interface IFraxGaugeFXSRewardsDistributor { function acceptOwnership() external; function curator_address() external view returns(address); function currentReward(address gauge_address) external view returns(uint256 reward_amount); function distributeReward(address gauge_address) external returns(uint256 weeks_elapsed, uint256 reward_tally); function distributionsOn() external view returns(bool); function gauge_whitelist(address) external view returns(bool); function is_middleman(address) external view returns(bool); function last_time_gauge_paid(address) external view returns(uint256); function nominateNewOwner(address _owner) external; function nominatedOwner() external view returns(address); function owner() external view returns(address); function recoverERC20(address tokenAddress, uint256 tokenAmount) external; function setCurator(address _new_curator_address) external; function setGaugeController(address _gauge_controller_address) external; function setGaugeState(address _gauge_address, bool _is_middleman, bool _is_active) external; function setTimelock(address _new_timelock) external; function timelock_address() external view returns(address); function toggleDistributions() external; } // File contracts/Curve/IveFXS.sol interface IveFXS { struct LockedBalance { int128 amount; uint256 end; } function commit_transfer_ownership(address addr) external; function apply_transfer_ownership() external; function commit_smart_wallet_checker(address addr) external; function apply_smart_wallet_checker() external; function toggleEmergencyUnlock() external; function recoverERC20(address token_addr, uint256 amount) external; function get_last_user_slope(address addr) external view returns (int128); function user_point_history__ts(address _addr, uint256 _idx) external view returns (uint256); function locked__end(address _addr) external view returns (uint256); function checkpoint() external; function deposit_for(address _addr, uint256 _value) external; function create_lock(uint256 _value, uint256 _unlock_time) external; function increase_amount(uint256 _value) external; function increase_unlock_time(uint256 _unlock_time) external; function withdraw() external; function balanceOf(address addr) external view returns (uint256); function balanceOf(address addr, uint256 _t) external view returns (uint256); function balanceOfAt(address addr, uint256 _block) external view returns (uint256); function totalSupply() external view returns (uint256); function totalSupply(uint256 t) external view returns (uint256); function totalSupplyAt(uint256 _block) external view returns (uint256); function totalFXSSupply() external view returns (uint256); function totalFXSSupplyAt(uint256 _block) external view returns (uint256); function changeController(address _newController) external; function token() external view returns (address); function supply() external view returns (uint256); function locked(address addr) external view returns (LockedBalance memory); function epoch() external view returns (uint256); function point_history(uint256 arg0) external view returns (int128 bias, int128 slope, uint256 ts, uint256 blk, uint256 fxs_amt); function user_point_history(address arg0, uint256 arg1) external view returns (int128 bias, int128 slope, uint256 ts, uint256 blk, uint256 fxs_amt); function user_point_epoch(address arg0) external view returns (uint256); function slope_changes(uint256 arg0) external view returns (int128); function controller() external view returns (address); function transfersEnabled() external view returns (bool); function emergencyUnlockActive() external view returns (bool); function name() external view returns (string memory); function symbol() external view returns (string memory); function version() external view returns (string memory); function decimals() external view returns (uint256); function future_smart_wallet_checker() external view returns (address); function smart_wallet_checker() external view returns (address); function admin() external view returns (address); function future_admin() external view returns (address); } // File contracts/Math/Math.sol /** * @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, so we distribute return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); } // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) function sqrt(uint y) internal pure returns (uint z) { if (y > 3) { z = y; uint x = y / 2 + 1; while (x < z) { z = x; x = (y / x + x) / 2; } } else if (y != 0) { z = 1; } } } // File contracts/Misc_AMOs/convex/IConvexBaseRewardPool.sol interface IConvexBaseRewardPool { function addExtraReward(address _reward) external returns (bool); function balanceOf(address account) external view returns (uint256); function clearExtraRewards() external; function currentRewards() external view returns (uint256); function donate(uint256 _amount) external returns (bool); function duration() external view returns (uint256); function earned(address account) external view returns (uint256); function extraRewards(uint256) external view returns (address); function extraRewardsLength() external view returns (uint256); function getReward() external returns (bool); function getReward(address _account, bool _claimExtras) external returns (bool); function historicalRewards() external view returns (uint256); function lastTimeRewardApplicable() external view returns (uint256); function lastUpdateTime() external view returns (uint256); function newRewardRatio() external view returns (uint256); function operator() external view returns (address); function periodFinish() external view returns (uint256); function pid() external view returns (uint256); function queueNewRewards(uint256 _rewards) external returns (bool); function queuedRewards() external view returns (uint256); function rewardManager() external view returns (address); function rewardPerToken() external view returns (uint256); function rewardPerTokenStored() external view returns (uint256); function rewardRate() external view returns (uint256); function rewardToken() external view returns (address); function rewards(address) external view returns (uint256); function stake(uint256 _amount) external returns (bool); function stakeAll() external returns (bool); function stakeFor(address _for, uint256 _amount) external returns (bool); function stakingToken() external view returns (address); function totalSupply() external view returns (uint256); function userRewardPerTokenPaid(address) external view returns (uint256); function withdraw(uint256 amount, bool claim) external returns (bool); function withdrawAll(bool claim) external; function withdrawAllAndUnwrap(bool claim) external; function withdrawAndUnwrap(uint256 amount, bool claim) external returns (bool); } // File contracts/Staking/Owned.sol // https://docs.synthetix.io/contracts/Owned contract Owned { address public owner; address public nominatedOwner; constructor (address _owner) public { require(_owner != address(0), "Owner address cannot be 0"); owner = _owner; emit OwnerChanged(address(0), _owner); } function nominateNewOwner(address _owner) external onlyOwner { nominatedOwner = _owner; emit OwnerNominated(_owner); } function acceptOwnership() external { require(msg.sender == nominatedOwner, "You must be nominated before you can accept ownership"); emit OwnerChanged(owner, nominatedOwner); owner = nominatedOwner; nominatedOwner = address(0); } modifier onlyOwner { require(msg.sender == owner, "Only the contract owner may perform this action"); _; } event OwnerNominated(address newOwner); event OwnerChanged(address oldOwner, address newOwner); } // File contracts/Uniswap/TransferHelper.sol // helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false library TransferHelper { function safeApprove(address token, address to, uint value) internal { // bytes4(keccak256(bytes('approve(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED'); } function safeTransfer(address token, address to, uint value) internal { // bytes4(keccak256(bytes('transfer(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED'); } function safeTransferFrom(address token, address from, address to, uint value) internal { // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED'); } function safeTransferETH(address to, uint value) internal { (bool success,) = to.call{value:value}(new bytes(0)); require(success, 'TransferHelper: ETH_TRANSFER_FAILED'); } } // File contracts/Utils/ReentrancyGuard.sol /** * @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 () internal { _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 make 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 contracts/Staking/FraxUnifiedFarmTemplate.sol // ==================================================================== // | ______ _______ | // | / _____________ __ __ / ____(_____ ____ _____ ________ | // | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ | // | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ | // | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ | // | | // ==================================================================== // ====================== FraxUnifiedFarmTemplate ===================== // ==================================================================== // Farming contract that accounts for veFXS // Overrideable for UniV3, ERC20s, etc // New for V2 // - Multiple reward tokens possible // - Can add to existing locked stakes // - Contract is aware of proxied veFXS // - veFXS multiplier formula changed // Apes together strong // Frax Finance: https://github.com/FraxFinance // Primary Author(s) // Travis Moore: https://github.com/FortisFortuna // Reviewer(s) / Contributor(s) // Jason Huan: https://github.com/jasonhuan // Sam Kazemian: https://github.com/samkazemian // Dennis: github.com/denett // Originally inspired by Synthetix.io, but heavily modified by the Frax team // (Locked, veFXS, and UniV3 portions are new) // https://raw.githubusercontent.com/Synthetixio/synthetix/develop/contracts/StakingRewards.sol // Extra rewards contract FraxUnifiedFarmTemplate is Owned, ReentrancyGuard { /* ========== STATE VARIABLES ========== */ // Instances IveFXS private immutable veFXS = IveFXS(0xc8418aF6358FFddA74e09Ca9CC3Fe03Ca6aDC5b0); // Frax related address internal immutable frax_address = 0x853d955aCEf822Db058eb8505911ED77F175b99e; uint256 public fraxPerLPStored; // Constant for various precisions uint256 internal constant MULTIPLIER_PRECISION = 1e18; // Time tracking uint256 public periodFinish; uint256 public lastUpdateTime; // Lock time and multiplier settings uint256 public lock_max_multiplier = uint256(2e18); // E18. 1x = e18 uint256 public lock_time_for_max_multiplier = 1 * 1095 * 86400; // 3 years // uint256 public lock_time_for_max_multiplier = 2 * 86400; // 2 days uint256 public lock_time_min = 594000; // 6.875 * 86400 (~7 day) // veFXS related uint256 public vefxs_boost_scale_factor = uint256(4e18); // E18. 4x = 4e18; 100 / scale_factor = % vefxs supply needed for max boost uint256 public vefxs_max_multiplier = uint256(2e18); // E18. 1x = 1e18 uint256 public vefxs_per_frax_for_max_boost = uint256(4e18); // E18. 2e18 means 2 veFXS must be held by the staker per 1 FRAX mapping(address => uint256) internal _vefxsMultiplierStored; mapping(address => bool) internal valid_vefxs_proxies; mapping(address => mapping(address => bool)) internal proxy_allowed_stakers; // Reward addresses, gauge addresses, reward rates, and reward managers mapping(address => address) public rewardManagers; // token addr -> manager addr address[] internal rewardTokens; address[] internal gaugeControllers; address[] internal rewardDistributors; uint256[] internal rewardRatesManual; mapping(address => uint256) public rewardTokenAddrToIdx; // token addr -> token index // Reward period uint256 public constant rewardsDuration = 604800; // 7 * 86400 (7 days) // Reward tracking uint256[] private rewardsPerTokenStored; mapping(address => mapping(uint256 => uint256)) private userRewardsPerTokenPaid; // staker addr -> token id -> paid amount mapping(address => mapping(uint256 => uint256)) private rewards; // staker addr -> token id -> reward amount mapping(address => uint256) public lastRewardClaimTime; // staker addr -> timestamp // Gauge tracking uint256[] private last_gauge_relative_weights; uint256[] private last_gauge_time_totals; // Balance tracking uint256 internal _total_liquidity_locked; uint256 internal _total_combined_weight; mapping(address => uint256) internal _locked_liquidity; mapping(address => uint256) internal _combined_weights; mapping(address => uint256) public proxy_lp_balances; // Keeps track of LP balances proxy-wide. Needed to make sure the proxy boost is kept in line // Stakers set which proxy(s) they want to use mapping(address => address) public staker_designated_proxies; // Keep public so users can see on the frontend if they have a proxy // Admin booleans for emergencies and overrides bool public stakesUnlocked; // Release locked stakes in case of emergency bool internal withdrawalsPaused; // For emergencies bool internal rewardsCollectionPaused; // For emergencies bool internal stakingPaused; // For emergencies /* ========== STRUCTS ========== */ // In children... /* ========== MODIFIERS ========== */ modifier onlyByOwnGov() { require(msg.sender == owner || msg.sender == 0x8412ebf45bAC1B340BbE8F318b928C466c4E39CA, "Not owner or timelock"); _; } modifier onlyTknMgrs(address reward_token_address) { require(msg.sender == owner || isTokenManagerFor(msg.sender, reward_token_address), "Not owner or tkn mgr"); _; } modifier updateRewardAndBalanceMdf(address account, bool sync_too) { updateRewardAndBalance(account, sync_too); _; } /* ========== CONSTRUCTOR ========== */ constructor ( address _owner, address[] memory _rewardTokens, address[] memory _rewardManagers, uint256[] memory _rewardRatesManual, address[] memory _gaugeControllers, address[] memory _rewardDistributors ) Owned(_owner) { // Address arrays rewardTokens = _rewardTokens; gaugeControllers = _gaugeControllers; rewardDistributors = _rewardDistributors; rewardRatesManual = _rewardRatesManual; for (uint256 i = 0; i < _rewardTokens.length; i++){ // For fast token address -> token ID lookups later rewardTokenAddrToIdx[_rewardTokens[i]] = i; // Initialize the stored rewards rewardsPerTokenStored.push(0); // Initialize the reward managers rewardManagers[_rewardTokens[i]] = _rewardManagers[i]; // Push in empty relative weights to initialize the array last_gauge_relative_weights.push(0); // Push in empty time totals to initialize the array last_gauge_time_totals.push(0); } // Other booleans stakesUnlocked = false; // Initialization lastUpdateTime = block.timestamp; periodFinish = block.timestamp + rewardsDuration; } /* ============= VIEWS ============= */ // ------ REWARD RELATED ------ // See if the caller_addr is a manager for the reward token function isTokenManagerFor(address caller_addr, address reward_token_addr) public view returns (bool){ if (caller_addr == owner) return true; // Contract owner else if (rewardManagers[reward_token_addr] == caller_addr) return true; // Reward manager return false; } // All the reward tokens function getAllRewardTokens() external view returns (address[] memory) { return rewardTokens; } // Last time the reward was applicable function lastTimeRewardApplicable() internal view returns (uint256) { return Math.min(block.timestamp, periodFinish); } function rewardRates(uint256 token_idx) public view returns (uint256 rwd_rate) { address gauge_controller_address = gaugeControllers[token_idx]; if (gauge_controller_address != address(0)) { rwd_rate = (IFraxGaugeController(gauge_controller_address).global_emission_rate() * last_gauge_relative_weights[token_idx]) / 1e18; } else { rwd_rate = rewardRatesManual[token_idx]; } } // Amount of reward tokens per LP token / liquidity unit function rewardsPerToken() public view returns (uint256[] memory newRewardsPerTokenStored) { if (_total_liquidity_locked == 0 || _total_combined_weight == 0) { return rewardsPerTokenStored; } else { newRewardsPerTokenStored = new uint256[](rewardTokens.length); for (uint256 i = 0; i < rewardsPerTokenStored.length; i++){ newRewardsPerTokenStored[i] = rewardsPerTokenStored[i] + ( ((lastTimeRewardApplicable() - lastUpdateTime) * rewardRates(i) * 1e18) / _total_combined_weight ); } return newRewardsPerTokenStored; } } // Amount of reward tokens an account has earned / accrued // Note: In the edge-case of one of the account's stake expiring since the last claim, this will // return a slightly inflated number function earned(address account) public view returns (uint256[] memory new_earned) { uint256[] memory reward_arr = rewardsPerToken(); new_earned = new uint256[](rewardTokens.length); if (_combined_weights[account] > 0){ for (uint256 i = 0; i < rewardTokens.length; i++){ new_earned[i] = ((_combined_weights[account] * (reward_arr[i] - userRewardsPerTokenPaid[account][i])) / 1e18) + rewards[account][i]; } } } // Total reward tokens emitted in the given period function getRewardForDuration() external view returns (uint256[] memory rewards_per_duration_arr) { rewards_per_duration_arr = new uint256[](rewardRatesManual.length); for (uint256 i = 0; i < rewardRatesManual.length; i++){ rewards_per_duration_arr[i] = rewardRates(i) * rewardsDuration; } } // ------ LIQUIDITY AND WEIGHTS ------ // User locked liquidity / LP tokens function totalLiquidityLocked() external view returns (uint256) { return _total_liquidity_locked; } // Total locked liquidity / LP tokens function lockedLiquidityOf(address account) external view returns (uint256) { return _locked_liquidity[account]; } // Total combined weight function totalCombinedWeight() external view returns (uint256) { return _total_combined_weight; } // Total 'balance' used for calculating the percent of the pool the account owns // Takes into account the locked stake time multiplier and veFXS multiplier function combinedWeightOf(address account) external view returns (uint256) { return _combined_weights[account]; } // Calculated the combined weight for an account function calcCurCombinedWeight(address account) public virtual view returns ( uint256 old_combined_weight, uint256 new_vefxs_multiplier, uint256 new_combined_weight ) { revert("Need cCCW logic"); } // ------ LOCK RELATED ------ // Multiplier amount, given the length of the lock function lockMultiplier(uint256 secs) public view returns (uint256) { // return Math.min( // lock_max_multiplier, // uint256(MULTIPLIER_PRECISION) + ( // (secs * (lock_max_multiplier - MULTIPLIER_PRECISION)) / lock_time_for_max_multiplier // ) // ) ; return Math.min( lock_max_multiplier, (secs * lock_max_multiplier) / lock_time_for_max_multiplier ) ; } // ------ FRAX RELATED ------ function userStakedFrax(address account) public view returns (uint256) { return (fraxPerLPStored * _locked_liquidity[account]) / MULTIPLIER_PRECISION; } function proxyStakedFrax(address proxy_address) public view returns (uint256) { return (fraxPerLPStored * proxy_lp_balances[proxy_address]) / MULTIPLIER_PRECISION; } // Max LP that can get max veFXS boosted for a given address at its current veFXS balance function maxLPForMaxBoost(address account) external view returns (uint256) { return (veFXS.balanceOf(account) * MULTIPLIER_PRECISION * MULTIPLIER_PRECISION) / (vefxs_per_frax_for_max_boost * fraxPerLPStored); } // Meant to be overridden function fraxPerLPToken() public virtual view returns (uint256) { revert("Need fPLPT logic"); } // ------ veFXS RELATED ------ function minVeFXSForMaxBoost(address account) public view returns (uint256) { return (userStakedFrax(account) * vefxs_per_frax_for_max_boost) / MULTIPLIER_PRECISION; } function minVeFXSForMaxBoostProxy(address proxy_address) public view returns (uint256) { return (proxyStakedFrax(proxy_address) * vefxs_per_frax_for_max_boost) / MULTIPLIER_PRECISION; } function getProxyFor(address addr) public view returns (address){ if (valid_vefxs_proxies[addr]) { // If addr itself is a proxy, return that. // If it farms itself directly, it should use the shared LP tally in proxyStakedFrax return addr; } else { // Otherwise, return the proxy, or address(0) return staker_designated_proxies[addr]; } } function veFXSMultiplier(address account) public view returns (uint256 vefxs_multiplier) { // Use either the user's or their proxy's veFXS balance uint256 vefxs_bal_to_use = 0; address the_proxy = getProxyFor(account); vefxs_bal_to_use = (the_proxy == address(0)) ? veFXS.balanceOf(account) : veFXS.balanceOf(the_proxy); // First option based on fraction of total veFXS supply, with an added scale factor uint256 mult_optn_1 = (vefxs_bal_to_use * vefxs_max_multiplier * vefxs_boost_scale_factor) / (veFXS.totalSupply() * MULTIPLIER_PRECISION); // Second based on old method, where the amount of FRAX staked comes into play uint256 mult_optn_2; { uint256 veFXS_needed_for_max_boost; // Need to use proxy-wide FRAX balance if applicable, to prevent exploiting veFXS_needed_for_max_boost = (the_proxy == address(0)) ? minVeFXSForMaxBoost(account) : minVeFXSForMaxBoostProxy(the_proxy); if (veFXS_needed_for_max_boost > 0){ uint256 user_vefxs_fraction = (vefxs_bal_to_use * MULTIPLIER_PRECISION) / veFXS_needed_for_max_boost; mult_optn_2 = (user_vefxs_fraction * vefxs_max_multiplier) / MULTIPLIER_PRECISION; } else mult_optn_2 = 0; // This will happen with the first stake, when user_staked_frax is 0 } // Select the higher of the two vefxs_multiplier = (mult_optn_1 > mult_optn_2 ? mult_optn_1 : mult_optn_2); // Cap the boost to the vefxs_max_multiplier if (vefxs_multiplier > vefxs_max_multiplier) vefxs_multiplier = vefxs_max_multiplier; } /* =============== MUTATIVE FUNCTIONS =============== */ // Proxy can allow a staker to use their veFXS balance (the staker will have to reciprocally toggle them too) // Must come before stakerSetVeFXSProxy // CALLED BY PROXY function proxyToggleStaker(address staker_address) external { require(valid_vefxs_proxies[msg.sender], "Invalid proxy"); proxy_allowed_stakers[msg.sender][staker_address] = !proxy_allowed_stakers[msg.sender][staker_address]; // Disable the staker's set proxy if it was the toggler and is currently on if (staker_designated_proxies[staker_address] == msg.sender){ staker_designated_proxies[staker_address] = address(0); // Remove the LP as well proxy_lp_balances[msg.sender] -= _locked_liquidity[staker_address]; } } // Staker can allow a veFXS proxy (the proxy will have to toggle them first) // CALLED BY STAKER function stakerSetVeFXSProxy(address proxy_address) external { require(valid_vefxs_proxies[proxy_address], "Invalid proxy"); require(proxy_allowed_stakers[proxy_address][msg.sender], "Proxy has not allowed you yet"); // Corner case sanity check to make sure LP isn't double counted address old_proxy_addr = staker_designated_proxies[msg.sender]; if (old_proxy_addr != address(0)) { // Remove the LP count from the old proxy proxy_lp_balances[old_proxy_addr] -= _locked_liquidity[msg.sender]; } // Set the new proxy staker_designated_proxies[msg.sender] = proxy_address; // Add the the LP as well proxy_lp_balances[proxy_address] += _locked_liquidity[msg.sender]; } // ------ STAKING ------ // In children... // ------ WITHDRAWING ------ // In children... // ------ REWARDS SYNCING ------ function updateRewardAndBalance(address account, bool sync_too) public { // Need to retro-adjust some things if the period hasn't been renewed, then start a new one if (sync_too){ sync(); } if (account != address(0)) { // To keep the math correct, the user's combined weight must be recomputed to account for their // ever-changing veFXS balance. ( uint256 old_combined_weight, uint256 new_vefxs_multiplier, uint256 new_combined_weight ) = calcCurCombinedWeight(account); // Calculate the earnings first _syncEarned(account); // Update the user's stored veFXS multipliers _vefxsMultiplierStored[account] = new_vefxs_multiplier; // Update the user's and the global combined weights if (new_combined_weight >= old_combined_weight) { uint256 weight_diff = new_combined_weight - old_combined_weight; _total_combined_weight = _total_combined_weight + weight_diff; _combined_weights[account] = old_combined_weight + weight_diff; } else { uint256 weight_diff = old_combined_weight - new_combined_weight; _total_combined_weight = _total_combined_weight - weight_diff; _combined_weights[account] = old_combined_weight - weight_diff; } } } function _syncEarned(address account) internal { if (account != address(0)) { // Calculate the earnings uint256[] memory earned_arr = earned(account); // Update the rewards array for (uint256 i = 0; i < earned_arr.length; i++){ rewards[account][i] = earned_arr[i]; } // Update the rewards paid array for (uint256 i = 0; i < earned_arr.length; i++){ userRewardsPerTokenPaid[account][i] = rewardsPerTokenStored[i]; } } } // ------ REWARDS CLAIMING ------ function getRewardExtraLogic(address destination_address) public nonReentrant { require(rewardsCollectionPaused == false, "Rewards collection paused"); return _getRewardExtraLogic(msg.sender, destination_address); } function _getRewardExtraLogic(address rewardee, address destination_address) internal virtual { revert("Need gREL logic"); } // Two different getReward functions are needed because of delegateCall and msg.sender issues // For backwards-compatibility function getReward(address destination_address) external nonReentrant returns (uint256[] memory) { return _getReward(msg.sender, destination_address, true); } function getReward2(address destination_address, bool claim_extra_too) external nonReentrant returns (uint256[] memory) { return _getReward(msg.sender, destination_address, claim_extra_too); } // No withdrawer == msg.sender check needed since this is only internally callable function _getReward(address rewardee, address destination_address, bool do_extra_logic) internal updateRewardAndBalanceMdf(rewardee, true) returns (uint256[] memory rewards_before) { // Update the last reward claim time first, as an extra reentrancy safeguard lastRewardClaimTime[rewardee] = block.timestamp; // Make sure rewards collection isn't paused require(rewardsCollectionPaused == false, "Rewards collection paused"); // Update the rewards array and distribute rewards rewards_before = new uint256[](rewardTokens.length); for (uint256 i = 0; i < rewardTokens.length; i++){ rewards_before[i] = rewards[rewardee][i]; rewards[rewardee][i] = 0; if (rewards_before[i] > 0) { TransferHelper.safeTransfer(rewardTokens[i], destination_address, rewards_before[i]); emit RewardPaid(rewardee, rewards_before[i], rewardTokens[i], destination_address); } } // Handle additional reward logic if (do_extra_logic) { _getRewardExtraLogic(rewardee, destination_address); } } // ------ FARM SYNCING ------ // If the period expired, renew it function retroCatchUp() internal { // Pull in rewards from the rewards distributor, if applicable for (uint256 i = 0; i < rewardDistributors.length; i++){ address reward_distributor_address = rewardDistributors[i]; if (reward_distributor_address != address(0)) { IFraxGaugeFXSRewardsDistributor(reward_distributor_address).distributeReward(address(this)); } } // 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. uint256 num_periods_elapsed = uint256(block.timestamp - periodFinish) / rewardsDuration; // Floor division to the nearest period // Make sure there are enough tokens to renew the reward period for (uint256 i = 0; i < rewardTokens.length; i++){ require((rewardRates(i) * rewardsDuration * (num_periods_elapsed + 1)) <= IERC20(rewardTokens[i]).balanceOf(address(this)), string(abi.encodePacked("Not enough reward tokens available: ", rewardTokens[i])) ); } // uint256 old_lastUpdateTime = lastUpdateTime; // uint256 new_lastUpdateTime = block.timestamp; // lastUpdateTime = periodFinish; periodFinish = periodFinish + ((num_periods_elapsed + 1) * rewardsDuration); // Update the rewards and time _updateStoredRewardsAndTime(); // Update the fraxPerLPStored fraxPerLPStored = fraxPerLPToken(); // Pull in rewards and set the reward rate for one week, based off of that // If the rewards get messed up for some reason, set this to 0 and it will skip // if (rewardRatesManual[1] != 0 && rewardRatesManual[2] != 0) { // // CRV & CVX // // ==================================== // uint256 crv_before = ERC20(rewardTokens[1]).balanceOf(address(this)); // uint256 cvx_before = ERC20(rewardTokens[2]).balanceOf(address(this)); // IConvexBaseRewardPool(0x329cb014b562d5d42927cfF0dEdF4c13ab0442EF).getReward( // address(this), // true // ); // uint256 crv_after = ERC20(rewardTokens[1]).balanceOf(address(this)); // uint256 cvx_after = ERC20(rewardTokens[2]).balanceOf(address(this)); // // Set the new reward rate // rewardRatesManual[1] = (crv_after - crv_before) / rewardsDuration; // rewardRatesManual[2] = (cvx_after - cvx_before) / rewardsDuration; // } } function _updateStoredRewardsAndTime() internal { // Get the rewards uint256[] memory rewards_per_token = rewardsPerToken(); // Update the rewardsPerTokenStored for (uint256 i = 0; i < rewardsPerTokenStored.length; i++){ rewardsPerTokenStored[i] = rewards_per_token[i]; } // Update the last stored time lastUpdateTime = lastTimeRewardApplicable(); } function sync_gauge_weights(bool force_update) public { // Loop through the gauge controllers for (uint256 i = 0; i < gaugeControllers.length; i++){ address gauge_controller_address = gaugeControllers[i]; if (gauge_controller_address != address(0)) { if (force_update || (block.timestamp > last_gauge_time_totals[i])){ // Update the gauge_relative_weight last_gauge_relative_weights[i] = IFraxGaugeController(gauge_controller_address).gauge_relative_weight_write(address(this), block.timestamp); last_gauge_time_totals[i] = IFraxGaugeController(gauge_controller_address).time_total(); } } } } function sync() public { // Sync the gauge weight, if applicable sync_gauge_weights(false); // Update the fraxPerLPStored fraxPerLPStored = fraxPerLPToken(); if (block.timestamp >= periodFinish) { retroCatchUp(); } else { _updateStoredRewardsAndTime(); } } /* ========== RESTRICTED FUNCTIONS - Curator callable ========== */ // ------ FARM SYNCING ------ // In children... // ------ PAUSES ------ function setPauses( bool _stakingPaused, bool _withdrawalsPaused, bool _rewardsCollectionPaused ) external onlyByOwnGov { stakingPaused = _stakingPaused; withdrawalsPaused = _withdrawalsPaused; rewardsCollectionPaused = _rewardsCollectionPaused; } /* ========== RESTRICTED FUNCTIONS - Owner or timelock only ========== */ function unlockStakes() external onlyByOwnGov { stakesUnlocked = !stakesUnlocked; } // Adds a valid veFXS proxy address function toggleValidVeFXSProxy(address _proxy_addr) external onlyByOwnGov { valid_vefxs_proxies[_proxy_addr] = !valid_vefxs_proxies[_proxy_addr]; } // Added to support recovering LP Rewards and other mistaken tokens from other systems to be distributed to holders function recoverERC20(address tokenAddress, uint256 tokenAmount) external onlyTknMgrs(tokenAddress) { // Check if the desired token is a reward token bool isRewardToken = false; for (uint256 i = 0; i < rewardTokens.length; i++){ if (rewardTokens[i] == tokenAddress) { isRewardToken = true; break; } } // Only the reward managers can take back their reward tokens // Also, other tokens, like the staking token, airdrops, or accidental deposits, can be withdrawn by the owner if ( (isRewardToken && rewardManagers[tokenAddress] == msg.sender) || (!isRewardToken && (msg.sender == owner)) ) { TransferHelper.safeTransfer(tokenAddress, msg.sender, tokenAmount); return; } // If none of the above conditions are true else { revert("No valid tokens to recover"); } } function setMiscVariables( uint256[6] memory _misc_vars // [0]: uint256 _lock_max_multiplier, // [1] uint256 _vefxs_max_multiplier, // [2] uint256 _vefxs_per_frax_for_max_boost, // [3] uint256 _vefxs_boost_scale_factor, // [4] uint256 _lock_time_for_max_multiplier, // [5] uint256 _lock_time_min ) external onlyByOwnGov { require(_misc_vars[0] >= MULTIPLIER_PRECISION, "Must be >= MUL PREC"); require((_misc_vars[1] >= 0) && (_misc_vars[2] >= 0) && (_misc_vars[3] >= 0), "Must be >= 0"); require((_misc_vars[4] >= 1) && (_misc_vars[5] >= 1), "Must be >= 1"); lock_max_multiplier = _misc_vars[0]; vefxs_max_multiplier = _misc_vars[1]; vefxs_per_frax_for_max_boost = _misc_vars[2]; vefxs_boost_scale_factor = _misc_vars[3]; lock_time_for_max_multiplier = _misc_vars[4]; lock_time_min = _misc_vars[5]; } // The owner or the reward token managers can set reward rates function setRewardVars(address reward_token_address, uint256 _new_rate, address _gauge_controller_address, address _rewards_distributor_address) external onlyTknMgrs(reward_token_address) { rewardRatesManual[rewardTokenAddrToIdx[reward_token_address]] = _new_rate; gaugeControllers[rewardTokenAddrToIdx[reward_token_address]] = _gauge_controller_address; rewardDistributors[rewardTokenAddrToIdx[reward_token_address]] = _rewards_distributor_address; } // The owner or the reward token managers can change managers function changeTokenManager(address reward_token_address, address new_manager_address) external onlyTknMgrs(reward_token_address) { rewardManagers[reward_token_address] = new_manager_address; } /* ========== EVENTS ========== */ event RewardPaid(address indexed user, uint256 amount, address token_address, address destination_address); /* ========== A CHICKEN ========== */ // // ,~. // ,-'__ `-, // {,-' `. } ,') // ,( a ) `-.__ ,',')~, // <=.) ( `-.__,==' ' ' '} // ( ) /) // `-'\ , ) // | \ `~. / // \ `._ \ / // \ `._____,' ,' // `-. ,' // `-._ _,-' // 77jj' // //_|| // __//--'/` // ,--'/` ' // // [hjw] https://textart.io/art/vw6Sa3iwqIRGkZsN1BC2vweF/chicken } // File contracts/Staking/FraxUnifiedFarm_ERC20.sol // ==================================================================== // | ______ _______ | // | / _____________ __ __ / ____(_____ ____ _____ ________ | // | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ | // | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ | // | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ | // | | // ==================================================================== // ======================= FraxUnifiedFarm_ERC20 ====================== // ==================================================================== // For ERC20 Tokens // Uses FraxUnifiedFarmTemplate.sol // -------------------- VARIES -------------------- // Convex wrappers // import "../Curve/ICurvefrxETHETHPool.sol"; // Fraxlend // import '../Fraxlend/IFraxlendPair.sol'; // Fraxswap // import '../Fraxswap/core/interfaces/IFraxswapPair.sol'; // G-UNI // import "../Misc_AMOs/gelato/IGUniPool.sol"; // mStable // import '../Misc_AMOs/mstable/IFeederPool.sol'; // StakeDAO sdETH-FraxPut // import '../Misc_AMOs/stakedao/IOpynPerpVault.sol'; // StakeDAO Vault // import '../Misc_AMOs/stakedao/IStakeDaoVault.sol'; // Uniswap V2 // import '../Uniswap/Interfaces/IUniswapV2Pair.sol'; // Vesper // import '../Misc_AMOs/vesper/IVPool.sol'; // ------------------------------------------------ contract FraxUnifiedFarm_ERC20 is FraxUnifiedFarmTemplate { /* ========== STATE VARIABLES ========== */ // -------------------- COMMON -------------------- bool internal frax_is_token0; // -------------------- VARIES -------------------- // Convex stkcvxFPIFRAX, stkcvxFRAXBP, etc IConvexStakingWrapperFrax public stakingToken; I2poolToken public curveToken; I2pool public curvePool; // ICurvefrxETHETHPool public curvePool; // Fraxswap // IFraxswapPair public stakingToken; // Fraxlend // IFraxlendPair public stakingToken; // G-UNI // IGUniPool public stakingToken; // mStable // IFeederPool public stakingToken; // sdETH-FraxPut Vault // IOpynPerpVault public stakingToken; // StakeDAO Vault // IStakeDaoVault public stakingToken; // Uniswap V2 // IUniswapV2Pair public stakingToken; // Vesper // IVPool public stakingToken; // ------------------------------------------------ // Stake tracking mapping(address => LockedStake[]) public lockedStakes; /* ========== STRUCTS ========== */ // Struct for the stake struct LockedStake { bytes32 kek_id; uint256 start_timestamp; uint256 liquidity; uint256 ending_timestamp; uint256 lock_multiplier; // 6 decimals of precision. 1x = 1000000 } /* ========== CONSTRUCTOR ========== */ constructor ( address _owner, address[] memory _rewardTokens, address[] memory _rewardManagers, uint256[] memory _rewardRatesManual, address[] memory _gaugeControllers, address[] memory _rewardDistributors, address _stakingToken ) FraxUnifiedFarmTemplate(_owner, _rewardTokens, _rewardManagers, _rewardRatesManual, _gaugeControllers, _rewardDistributors) { // -------------------- VARIES (USE CHILD FOR LOGIC) -------------------- // Convex stkcvxFPIFRAX, stkcvxFRAXBP, etc // USE CHILD // Fraxlend // USE CHILD // Fraxswap // USE CHILD // G-UNI // stakingToken = IGUniPool(_stakingToken); // address token0 = address(stakingToken.token0()); // frax_is_token0 = (token0 == frax_address); // mStable // stakingToken = IFeederPool(_stakingToken); // StakeDAO sdETH-FraxPut Vault // stakingToken = IOpynPerpVault(_stakingToken); // StakeDAO Vault // stakingToken = IStakeDaoVault(_stakingToken); // Uniswap V2 // stakingToken = IUniswapV2Pair(_stakingToken); // address token0 = stakingToken.token0(); // if (token0 == frax_address) frax_is_token0 = true; // else frax_is_token0 = false; // Vesper // stakingToken = IVPool(_stakingToken); } /* ============= VIEWS ============= */ // ------ FRAX RELATED ------ function fraxPerLPToken() public virtual view override returns (uint256) { // Get the amount of FRAX 'inside' of the lp tokens uint256 frax_per_lp_token; // Convex stkcvxFPIFRAX and stkcvxFRAXBP only // ============================================ // USE CHILD // Convex Stable/FRAXBP // ============================================ // USE CHILD // Convex Volatile/FRAXBP // ============================================ // USE CHILD // Fraxlend // ============================================ // USE CHILD // Fraxswap // ============================================ // USE CHILD // G-UNI // ============================================ // { // (uint256 reserve0, uint256 reserve1) = stakingToken.getUnderlyingBalances(); // uint256 total_frax_reserves = frax_is_token0 ? reserve0 : reserve1; // frax_per_lp_token = (total_frax_reserves * 1e18) / stakingToken.totalSupply(); // } // mStable // ============================================ // { // uint256 total_frax_reserves; // (, IFeederPool.BassetData memory vaultData) = (stakingToken.getBasset(frax_address)); // total_frax_reserves = uint256(vaultData.vaultBalance); // frax_per_lp_token = (total_frax_reserves * 1e18) / stakingToken.totalSupply(); // } // StakeDAO sdETH-FraxPut Vault // ============================================ // { // uint256 frax3crv_held = stakingToken.totalUnderlyingControlled(); // // Optimistically assume 50/50 FRAX/3CRV ratio in the metapool to save gas // frax_per_lp_token = ((frax3crv_held * 1e18) / stakingToken.totalSupply()) / 2; // } // StakeDAO Vault // ============================================ // { // uint256 frax3crv_held = stakingToken.balance(); // // Optimistically assume 50/50 FRAX/3CRV ratio in the metapool to save gas // frax_per_lp_token = ((frax3crv_held * 1e18) / stakingToken.totalSupply()) / 2; // } // Uniswap V2 // ============================================ // { // uint256 total_frax_reserves; // (uint256 reserve0, uint256 reserve1, ) = (stakingToken.getReserves()); // if (frax_is_token0) total_frax_reserves = reserve0; // else total_frax_reserves = reserve1; // frax_per_lp_token = (total_frax_reserves * 1e18) / stakingToken.totalSupply(); // } // Vesper // ============================================ // frax_per_lp_token = stakingToken.pricePerShare(); return frax_per_lp_token; } // ------ LIQUIDITY AND WEIGHTS ------ function calcCurrLockMultiplier(address account, uint256 stake_idx) public view returns (uint256 midpoint_lock_multiplier) { // Get the stake LockedStake memory thisStake = lockedStakes[account][stake_idx]; // Handles corner case where user never claims for a new stake // Don't want the multiplier going above the max uint256 accrue_start_time; if (lastRewardClaimTime[account] < thisStake.start_timestamp) { accrue_start_time = thisStake.start_timestamp; } else { accrue_start_time = lastRewardClaimTime[account]; } // If the lock is expired if (thisStake.ending_timestamp <= block.timestamp) { // If the lock expired in the time since the last claim, the weight needs to be proportionately averaged this time if (lastRewardClaimTime[account] < thisStake.ending_timestamp){ uint256 time_before_expiry = thisStake.ending_timestamp - accrue_start_time; uint256 time_after_expiry = block.timestamp - thisStake.ending_timestamp; // Average the pre-expiry lock multiplier uint256 pre_expiry_avg_multiplier = lockMultiplier(time_before_expiry / 2); // Get the weighted-average lock_multiplier // uint256 numerator = (pre_expiry_avg_multiplier * time_before_expiry) + (MULTIPLIER_PRECISION * time_after_expiry); uint256 numerator = (pre_expiry_avg_multiplier * time_before_expiry) + (0 * time_after_expiry); midpoint_lock_multiplier = numerator / (time_before_expiry + time_after_expiry); } else { // Otherwise, it needs to just be 1x // midpoint_lock_multiplier = MULTIPLIER_PRECISION; // Otherwise, it needs to just be 0x midpoint_lock_multiplier = 0; } } // If the lock is not expired else { // Decay the lock multiplier based on the time left uint256 avg_time_left; { uint256 time_left_p1 = thisStake.ending_timestamp - accrue_start_time; uint256 time_left_p2 = thisStake.ending_timestamp - block.timestamp; avg_time_left = (time_left_p1 + time_left_p2) / 2; } midpoint_lock_multiplier = lockMultiplier(avg_time_left); } // Sanity check: make sure it never goes above the initial multiplier if (midpoint_lock_multiplier > thisStake.lock_multiplier) midpoint_lock_multiplier = thisStake.lock_multiplier; } // Calculate the combined weight for an account function calcCurCombinedWeight(address account) public override view returns ( uint256 old_combined_weight, uint256 new_vefxs_multiplier, uint256 new_combined_weight ) { // Get the old combined weight old_combined_weight = _combined_weights[account]; // Get the veFXS multipliers // For the calculations, use the midpoint (analogous to midpoint Riemann sum) new_vefxs_multiplier = veFXSMultiplier(account); uint256 midpoint_vefxs_multiplier; if ( (_locked_liquidity[account] == 0 && _combined_weights[account] == 0) || (new_vefxs_multiplier >= _vefxsMultiplierStored[account]) ) { // This is only called for the first stake to make sure the veFXS multiplier is not cut in half // Also used if the user increased or maintained their position midpoint_vefxs_multiplier = new_vefxs_multiplier; } else { // Handles natural decay with a non-increased veFXS position midpoint_vefxs_multiplier = (new_vefxs_multiplier + _vefxsMultiplierStored[account]) / 2; } // Loop through the locked stakes, first by getting the liquidity * lock_multiplier portion new_combined_weight = 0; for (uint256 i = 0; i < lockedStakes[account].length; i++) { LockedStake memory thisStake = lockedStakes[account][i]; // Calculate the midpoint lock multiplier uint256 midpoint_lock_multiplier = calcCurrLockMultiplier(account, i); // Calculate the combined boost uint256 liquidity = thisStake.liquidity; uint256 combined_boosted_amount = liquidity + ((liquidity * (midpoint_lock_multiplier + midpoint_vefxs_multiplier)) / MULTIPLIER_PRECISION); new_combined_weight += combined_boosted_amount; } } // ------ LOCK RELATED ------ // All the locked stakes for a given account function lockedStakesOf(address account) external view returns (LockedStake[] memory) { return lockedStakes[account]; } // Returns the length of the locked stakes for a given account function lockedStakesOfLength(address account) external view returns (uint256) { return lockedStakes[account].length; } // // All the locked stakes for a given account [old-school method] // function lockedStakesOfMultiArr(address account) external view returns ( // bytes32[] memory kek_ids, // uint256[] memory start_timestamps, // uint256[] memory liquidities, // uint256[] memory ending_timestamps, // uint256[] memory lock_multipliers // ) { // for (uint256 i = 0; i < lockedStakes[account].length; i++){ // LockedStake memory thisStake = lockedStakes[account][i]; // kek_ids[i] = thisStake.kek_id; // start_timestamps[i] = thisStake.start_timestamp; // liquidities[i] = thisStake.liquidity; // ending_timestamps[i] = thisStake.ending_timestamp; // lock_multipliers[i] = thisStake.lock_multiplier; // } // } /* =============== MUTATIVE FUNCTIONS =============== */ // ------ STAKING ------ function _updateLiqAmts(address staker_address, uint256 amt, bool is_add) internal { // Get the proxy address address the_proxy = getProxyFor(staker_address); if (is_add) { // Update total liquidities _total_liquidity_locked += amt; _locked_liquidity[staker_address] += amt; // Update the proxy if (the_proxy != address(0)) proxy_lp_balances[the_proxy] += amt; } else { // Update total liquidities _total_liquidity_locked -= amt; _locked_liquidity[staker_address] -= amt; // Update the proxy if (the_proxy != address(0)) proxy_lp_balances[the_proxy] -= amt; } // Need to call to update the combined weights updateRewardAndBalance(staker_address, false); } function _getStake(address staker_address, bytes32 kek_id) internal view returns (LockedStake memory locked_stake, uint256 arr_idx) { for (uint256 i = 0; i < lockedStakes[staker_address].length; i++){ if (kek_id == lockedStakes[staker_address][i].kek_id){ locked_stake = lockedStakes[staker_address][i]; arr_idx = i; break; } } require(locked_stake.kek_id == kek_id, "Stake not found"); } // Add additional LPs to an existing locked stake function lockAdditional(bytes32 kek_id, uint256 addl_liq) nonReentrant updateRewardAndBalanceMdf(msg.sender, true) public { // Get the stake and its index (LockedStake memory thisStake, uint256 theArrayIndex) = _getStake(msg.sender, kek_id); // Calculate the new amount uint256 new_amt = thisStake.liquidity + addl_liq; // Checks require(addl_liq >= 0, "Must be positive"); // Pull the tokens from the sender TransferHelper.safeTransferFrom(address(stakingToken), msg.sender, address(this), addl_liq); // Update the stake lockedStakes[msg.sender][theArrayIndex] = LockedStake( kek_id, thisStake.start_timestamp, new_amt, thisStake.ending_timestamp, thisStake.lock_multiplier ); // Update liquidities _updateLiqAmts(msg.sender, addl_liq, true); emit LockedAdditional(msg.sender, kek_id, addl_liq); } // Extends the lock of an existing stake function lockLonger(bytes32 kek_id, uint256 new_ending_ts) nonReentrant updateRewardAndBalanceMdf(msg.sender, true) public { // Get the stake and its index (LockedStake memory thisStake, uint256 theArrayIndex) = _getStake(msg.sender, kek_id); // Check require(new_ending_ts > block.timestamp, "Must be in the future"); // Calculate some times uint256 time_left = (thisStake.ending_timestamp > block.timestamp) ? thisStake.ending_timestamp - block.timestamp : 0; uint256 new_secs = new_ending_ts - block.timestamp; // Checks // require(time_left > 0, "Already expired"); require(new_secs > time_left, "Cannot shorten lock time"); require(new_secs >= lock_time_min, "Minimum stake time not met"); require(new_secs <= lock_time_for_max_multiplier, "Trying to lock for too long"); // Update the stake lockedStakes[msg.sender][theArrayIndex] = LockedStake( kek_id, block.timestamp, thisStake.liquidity, new_ending_ts, lockMultiplier(new_secs) ); // Need to call to update the combined weights updateRewardAndBalance(msg.sender, false); emit LockedLonger(msg.sender, kek_id, new_secs, block.timestamp, new_ending_ts); } // Two different stake functions are needed because of delegateCall and msg.sender issues (important for proxies) function stakeLocked(uint256 liquidity, uint256 secs) nonReentrant external returns (bytes32) { return _stakeLocked(msg.sender, msg.sender, liquidity, secs, block.timestamp); } // If this were not internal, and source_address had an infinite approve, this could be exploitable // (pull funds from source_address and stake for an arbitrary staker_address) function _stakeLocked( address staker_address, address source_address, uint256 liquidity, uint256 secs, uint256 start_timestamp ) internal updateRewardAndBalanceMdf(staker_address, true) returns (bytes32) { require(stakingPaused == false, "Staking paused"); require(secs >= lock_time_min, "Minimum stake time not met"); require(secs <= lock_time_for_max_multiplier,"Trying to lock for too long"); // Pull in the required token(s) // Varies per farm TransferHelper.safeTransferFrom(address(stakingToken), source_address, address(this), liquidity); // Get the lock multiplier and kek_id uint256 lock_multiplier = lockMultiplier(secs); bytes32 kek_id = keccak256(abi.encodePacked(staker_address, start_timestamp, liquidity, _locked_liquidity[staker_address])); // Create the locked stake lockedStakes[staker_address].push(LockedStake( kek_id, start_timestamp, liquidity, start_timestamp + secs, lock_multiplier )); // Update liquidities _updateLiqAmts(staker_address, liquidity, true); emit StakeLocked(staker_address, liquidity, secs, kek_id, source_address); return kek_id; } // ------ WITHDRAWING ------ // Two different withdrawLocked functions are needed because of delegateCall and msg.sender issues (important for proxies) function withdrawLocked(bytes32 kek_id, address destination_address) nonReentrant external returns (uint256) { require(withdrawalsPaused == false, "Withdrawals paused"); return _withdrawLocked(msg.sender, destination_address, kek_id); } // No withdrawer == msg.sender check needed since this is only internally callable and the checks are done in the wrapper function _withdrawLocked( address staker_address, address destination_address, bytes32 kek_id ) internal returns (uint256) { // Collect rewards first and then update the balances _getReward(staker_address, destination_address, true); // Get the stake and its index (LockedStake memory thisStake, uint256 theArrayIndex) = _getStake(staker_address, kek_id); require(block.timestamp >= thisStake.ending_timestamp || stakesUnlocked == true, "Stake is still locked!"); uint256 liquidity = thisStake.liquidity; if (liquidity > 0) { // Give the tokens to the destination_address // Should throw if insufficient balance TransferHelper.safeTransfer(address(stakingToken), destination_address, liquidity); // Remove the stake from the array delete lockedStakes[staker_address][theArrayIndex]; // Update liquidities _updateLiqAmts(staker_address, liquidity, false); emit WithdrawLocked(staker_address, liquidity, kek_id, destination_address); } return liquidity; } function _getRewardExtraLogic(address rewardee, address destination_address) internal override { // Do nothing } /* ========== RESTRICTED FUNCTIONS - Owner or timelock only ========== */ // Inherited... /* ========== EVENTS ========== */ event LockedAdditional(address indexed user, bytes32 kek_id, uint256 amount); event LockedLonger(address indexed user, bytes32 kek_id, uint256 new_secs, uint256 new_start_ts, uint256 new_end_ts); event StakeLocked(address indexed user, uint256 amount, uint256 secs, bytes32 kek_id, address source_address); event WithdrawLocked(address indexed user, uint256 liquidity, bytes32 kek_id, address destination_address); } // File contracts/Staking/Variants/FraxUnifiedFarm_ERC20_Convex_FRAXBP_Volatile.sol contract FraxUnifiedFarm_ERC20_Convex_FRAXBP_Volatile is FraxUnifiedFarm_ERC20 { constructor ( address _owner, address[] memory _rewardTokens, address[] memory _rewardManagers, uint256[] memory _rewardRates, address[] memory _gaugeControllers, address[] memory _rewardDistributors, address _stakingToken ) FraxUnifiedFarm_ERC20(_owner , _rewardTokens, _rewardManagers, _rewardRates, _gaugeControllers, _rewardDistributors, _stakingToken) { // COMMENTED OUT SO COMPILER DOESNT COMPLAIN. UNCOMMENT WHEN DEPLOYING // Convex stkcvxFPIFRAX and stkcvxFRAXBP. Also Volatile/FRAXBP stakingToken = IConvexStakingWrapperFrax(_stakingToken); curveToken = I2poolToken(stakingToken.curveToken()); curvePool = I2pool(curveToken.minter()); address token0 = curvePool.coins(0); frax_is_token0 = (token0 == frax_address); } function fraxPerLPToken() public view override returns (uint256) { // COMMENTED OUT SO COMPILER DOESNT COMPLAIN. UNCOMMENT WHEN DEPLOYING // Get the amount of FRAX 'inside' of the lp tokens uint256 frax_per_lp_token; // Convex Volatile/FRAXBP // ============================================ { // Half of the LP is FRAXBP. Half of that should be FRAX. // Using 0.25 * lp price for gas savings frax_per_lp_token = (curvePool.lp_price() * (1e18)) / (4 * curvePool.price_oracle()); } return frax_per_lp_token; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address[]","name":"_rewardTokens","type":"address[]"},{"internalType":"address[]","name":"_rewardManagers","type":"address[]"},{"internalType":"uint256[]","name":"_rewardRates","type":"uint256[]"},{"internalType":"address[]","name":"_gaugeControllers","type":"address[]"},{"internalType":"address[]","name":"_rewardDistributors","type":"address[]"},{"internalType":"address","name":"_stakingToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"bytes32","name":"kek_id","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LockedAdditional","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"bytes32","name":"kek_id","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"new_secs","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"new_start_ts","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"new_end_ts","type":"uint256"}],"name":"LockedLonger","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerNominated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"token_address","type":"address"},{"indexed":false,"internalType":"address","name":"destination_address","type":"address"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"secs","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"kek_id","type":"bytes32"},{"indexed":false,"internalType":"address","name":"source_address","type":"address"}],"name":"StakeLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"liquidity","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"kek_id","type":"bytes32"},{"indexed":false,"internalType":"address","name":"destination_address","type":"address"}],"name":"WithdrawLocked","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"calcCurCombinedWeight","outputs":[{"internalType":"uint256","name":"old_combined_weight","type":"uint256"},{"internalType":"uint256","name":"new_vefxs_multiplier","type":"uint256"},{"internalType":"uint256","name":"new_combined_weight","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"stake_idx","type":"uint256"}],"name":"calcCurrLockMultiplier","outputs":[{"internalType":"uint256","name":"midpoint_lock_multiplier","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"reward_token_address","type":"address"},{"internalType":"address","name":"new_manager_address","type":"address"}],"name":"changeTokenManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"combinedWeightOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"curvePool","outputs":[{"internalType":"contract I2pool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"curveToken","outputs":[{"internalType":"contract I2poolToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"earned","outputs":[{"internalType":"uint256[]","name":"new_earned","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fraxPerLPStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fraxPerLPToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllRewardTokens","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getProxyFor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"destination_address","type":"address"}],"name":"getReward","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"destination_address","type":"address"},{"internalType":"bool","name":"claim_extra_too","type":"bool"}],"name":"getReward2","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"destination_address","type":"address"}],"name":"getRewardExtraLogic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getRewardForDuration","outputs":[{"internalType":"uint256[]","name":"rewards_per_duration_arr","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"caller_addr","type":"address"},{"internalType":"address","name":"reward_token_addr","type":"address"}],"name":"isTokenManagerFor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastRewardClaimTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastUpdateTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"kek_id","type":"bytes32"},{"internalType":"uint256","name":"addl_liq","type":"uint256"}],"name":"lockAdditional","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"kek_id","type":"bytes32"},{"internalType":"uint256","name":"new_ending_ts","type":"uint256"}],"name":"lockLonger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"secs","type":"uint256"}],"name":"lockMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lock_max_multiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lock_time_for_max_multiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lock_time_min","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"lockedLiquidityOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"lockedStakes","outputs":[{"internalType":"bytes32","name":"kek_id","type":"bytes32"},{"internalType":"uint256","name":"start_timestamp","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"ending_timestamp","type":"uint256"},{"internalType":"uint256","name":"lock_multiplier","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"lockedStakesOf","outputs":[{"components":[{"internalType":"bytes32","name":"kek_id","type":"bytes32"},{"internalType":"uint256","name":"start_timestamp","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"ending_timestamp","type":"uint256"},{"internalType":"uint256","name":"lock_multiplier","type":"uint256"}],"internalType":"struct FraxUnifiedFarm_ERC20.LockedStake[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"lockedStakesOfLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"maxLPForMaxBoost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"minVeFXSForMaxBoost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"proxy_address","type":"address"}],"name":"minVeFXSForMaxBoostProxy","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"nominateNewOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nominatedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periodFinish","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"proxy_address","type":"address"}],"name":"proxyStakedFrax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"staker_address","type":"address"}],"name":"proxyToggleStaker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"proxy_lp_balances","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":[{"internalType":"address","name":"","type":"address"}],"name":"rewardManagers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"token_idx","type":"uint256"}],"name":"rewardRates","outputs":[{"internalType":"uint256","name":"rwd_rate","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardTokenAddrToIdx","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":"rewardsPerToken","outputs":[{"internalType":"uint256[]","name":"newRewardsPerTokenStored","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[6]","name":"_misc_vars","type":"uint256[6]"}],"name":"setMiscVariables","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_stakingPaused","type":"bool"},{"internalType":"bool","name":"_withdrawalsPaused","type":"bool"},{"internalType":"bool","name":"_rewardsCollectionPaused","type":"bool"}],"name":"setPauses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"reward_token_address","type":"address"},{"internalType":"uint256","name":"_new_rate","type":"uint256"},{"internalType":"address","name":"_gauge_controller_address","type":"address"},{"internalType":"address","name":"_rewards_distributor_address","type":"address"}],"name":"setRewardVars","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"secs","type":"uint256"}],"name":"stakeLocked","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"proxy_address","type":"address"}],"name":"stakerSetVeFXSProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"staker_designated_proxies","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakesUnlocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"contract IConvexStakingWrapperFrax","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sync","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"force_update","type":"bool"}],"name":"sync_gauge_weights","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_proxy_addr","type":"address"}],"name":"toggleValidVeFXSProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalCombinedWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalLiquidityLocked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unlockStakes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"sync_too","type":"bool"}],"name":"updateRewardAndBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"userStakedFrax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"veFXSMultiplier","outputs":[{"internalType":"uint256","name":"vefxs_multiplier","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vefxs_boost_scale_factor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vefxs_max_multiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vefxs_per_frax_for_max_boost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"kek_id","type":"bytes32"},{"internalType":"address","name":"destination_address","type":"address"}],"name":"withdrawLocked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60c060405273c8418af6358ffdda74e09ca9cc3fe03ca6adc5b060805273853d955acef822db058eb8505911ed77f175b99e60a052671bc16d674ec8000060068190556305a39a8060075562091050600855673782dace9d9000006009819055600a91909155600b553480156200007557600080fd5b506040516200582e3803806200582e833981016040819052620000989162000763565b86868686868686868686868686856001600160a01b038116620001015760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f74206265203000000000000000604482015260640160405180910390fd5b600080546001600160a01b0319166001600160a01b03831690811782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a15060016002558451620001739060109060208801906200053a565b508151620001899060119060208501906200053a565b5080516200019f9060129060208401906200053a565b508251620001b5906013906020860190620005a4565b5060005b855181101562000320578060146000888481518110620001dd57620001dd6200086a565b6020908102919091018101516001600160a01b03168252810191909152604001600090812091909155601580546001810182559082527f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec475015584518590829081106200024d576200024d6200086a565b6020026020010151600f60008884815181106200026e576200026e6200086a565b6020908102919091018101516001600160a01b03908116835290820192909252604001600090812080546001600160a01b031916939092169290921790556019805460018181019092557f944998273e477b495144fb8794c914197f3ccb46be2900f4698fd0ef743c969501829055601a8054918201815582527f057c384a7d1c54f3a1b2e5e67b2617b8224fdfd1ea7234eea573a6ff665ff63e015580620003178162000896565b915050620001b9565b506021805460ff19169055426005819055620003419062093a8090620008b2565b6004819055505050505050505050505050505080602160056101000a8154816001600160a01b0302191690836001600160a01b03160217905550602160059054906101000a90046001600160a01b03166001600160a01b0316634f39059c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620003cf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003f59190620008ce565b602280546001600160a01b0319166001600160a01b03929092169182179055604080516303aa30b960e11b815290516307546172916004808201926020929091908290030181865afa15801562000450573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004769190620008ce565b602380546001600160a01b0319166001600160a01b0392909216918217905560405163c661065760e01b8152600060048201819052919063c661065790602401602060405180830381865afa158015620004d4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004fa9190620008ce565b905060a0516001600160a01b0316816001600160a01b031614602160046101000a81548160ff0219169083151502179055505050505050505050620008f3565b82805482825590600052602060002090810192821562000592579160200282015b828111156200059257825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906200055b565b50620005a0929150620005e2565b5090565b82805482825590600052602060002090810192821562000592579160200282015b8281111562000592578251825591602001919060010190620005c5565b5b80821115620005a05760008155600101620005e3565b80516001600160a01b03811681146200061157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171562000657576200065762000616565b604052919050565b60006001600160401b038211156200067b576200067b62000616565b5060051b60200190565b600082601f8301126200069757600080fd5b81516020620006b0620006aa836200065f565b6200062c565b82815260059290921b84018101918181019086841115620006d057600080fd5b8286015b84811015620006f657620006e881620005f9565b8352918301918301620006d4565b509695505050505050565b600082601f8301126200071357600080fd5b8151602062000726620006aa836200065f565b82815260059290921b840181019181810190868411156200074657600080fd5b8286015b84811015620006f657805183529183019183016200074a565b600080600080600080600060e0888a0312156200077f57600080fd5b6200078a88620005f9565b60208901519097506001600160401b0380821115620007a857600080fd5b620007b68b838c0162000685565b975060408a0151915080821115620007cd57600080fd5b620007db8b838c0162000685565b965060608a0151915080821115620007f257600080fd5b620008008b838c0162000701565b955060808a01519150808211156200081757600080fd5b620008258b838c0162000685565b945060a08a01519150808211156200083c57600080fd5b506200084b8a828b0162000685565b9250506200085c60c08901620005f9565b905092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201620008ab57620008ab62000880565b5060010190565b80820180821115620008c857620008c862000880565b92915050565b600060208284031215620008e157600080fd5b620008ec82620005f9565b9392505050565b60805160a051614f036200092b600039600050506000818161103d015281816110f20152818161116c015261215c0152614f036000f3fe608060405234801561001057600080fd5b50600436106104055760003560e01c80638980f11f1161021a578063d2fbdc0d11610135578063e44b9fa5116100c8578063f2a8d34911610097578063f77e34d11161007c578063f77e34d1146109cd578063facefb64146109e0578063fff6cae9146109f357600080fd5b8063f2a8d349146109b1578063f2caeb1e146109ba57600080fd5b8063e44b9fa514610979578063e7f305821461098c578063ebe2b12b1461099f578063f288baf6146109a857600080fd5b8063d9f96e8d11610104578063d9f96e8d14610920578063de1a655114610956578063e01f62bf14610969578063e1ba95d21461097157600080fd5b8063d2fbdc0d146108d4578063d42fc9b4146108e7578063d5e1a9c6146108fa578063d7400d561461090d57600080fd5b8063b94c4dcb116101ad578063ca6df29d1161017c578063ca6df29d14610879578063cc2abd64146108af578063cdc82e80146108c2578063d2010fb4146108cb57600080fd5b8063b94c4dcb14610841578063c00007b01461084a578063c35438261461085d578063c8f33c911461087057600080fd5b80639637927f116101e95780639637927f14610805578063a0f2347614610812578063aa1d4fce14610825578063b85efd061461082e57600080fd5b80638980f11f146107915780638bad86a7146107a45780638da5cb5b146107d257806391cf600a146107f257600080fd5b80634f39059c116103255780636e27cef9116102b85780637910d17b1161028757806379ba50971161026c57806379ba5097146107565780637d6ef08e1461075e5780637f472e541461077e57600080fd5b80637910d17b146107085780637970833e1461071b57600080fd5b80636e27cef9146106bb57806370641a36146106c457806372f702f3146106cc578063774d4ae7146106f557600080fd5b80635bfd9258116102f45780635bfd92581461066b57806364f2c06014610673578063693392451461067b5780636c430dbb1461069b57600080fd5b80634f39059c146106055780634fd2b5361461062557806353a47bb714610638578063551897731461065857600080fd5b8063218751b21161039d57806336f89af21161036c57806336f89af21461057c578063386a9525146105b2578063387edc86146105bc57806341a16f3f146105cf57600080fd5b8063218751b2146104cc578063231b68dc1461051157806328408bab146105345780632c0c2a0a1461056957600080fd5b806317b18c89116103d957806317b18c891461047e5780631c1f78eb146104915780631e090f01146104995780631face856146104b957600080fd5b80628cc2621461040a5780630d7bac4f1461043357806312edb24c146104545780631627540c14610469575b600080fd5b61041d610418366004614930565b6109fb565b60405161042a919061494b565b60405180910390f35b61044661044136600461498f565b610b7a565b60405190815260200161042a565b61045c610ba6565b60405161042a91906149a8565b61047c610477366004614930565b610c15565b005b61044661048c3660046149f6565b610d3a565b61041d610dc4565b6104ac6104a7366004614930565b610e65565b60405161042a9190614a18565b6104466104c7366004614930565b610f19565b6023546104ec9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161042a565b61052461051f366004614a86565b610f5f565b604051901515815260200161042a565b6104ec610542366004614930565b602080526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b610446610577366004614930565b610fcd565b61044661058a366004614930565b73ffffffffffffffffffffffffffffffffffffffff166000908152601e602052604090205490565b61044662093a8081565b61047c6105ca366004614930565b6112e1565b6104ec6105dd366004614930565b600f6020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b6022546104ec9073ffffffffffffffffffffffffffffffffffffffff1681565b610446610633366004614930565b6113cb565b6001546104ec9073ffffffffffffffffffffffffffffffffffffffff1681565b61047c610666366004614ac7565b6113ec565b610446611510565b601c54610446565b610446610689366004614930565b60146020526000908152604090205481565b6104466106a9366004614930565b60186020526000908152604090205481565b61044660085481565b61041d611652565b6021546104ec9065010000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b610446610703366004614afe565b6117b1565b61041d610716366004614ac7565b6119bd565b61072e610729366004614afe565b611a39565b604080519586526020860194909452928401919091526060830152608082015260a00161042a565b61047c611a87565b61044661076c366004614930565b601f6020526000908152604090205481565b61044661078c366004614930565b611bd2565b61047c61079f366004614afe565b611be9565b6107b76107b2366004614930565b611dd2565b6040805193845260208401929092529082015260600161042a565b6000546104ec9073ffffffffffffffffffffffffffffffffffffffff1681565b61047c610800366004614930565b612006565b6021546105249060ff1681565b610446610820366004614930565b6120f9565b61044660095481565b61047c61083c3660046149f6565b6121d1565b61044660075481565b61041d610858366004614930565b61238a565b6104ec61086b366004614930565b612412565b61044660055481565b610446610887366004614930565b73ffffffffffffffffffffffffffffffffffffffff1660009081526024602052604090205490565b61047c6108bd366004614b28565b612474565b61044660065481565b61044660035481565b61047c6108e23660046149f6565b6125aa565b6104466108f5366004614930565b61290e565b61047c610908366004614b73565b61294a565b61047c61091b366004614930565b612b39565b61044661092e366004614930565b73ffffffffffffffffffffffffffffffffffffffff166000908152601d602052604090205490565b61047c610964366004614a86565b612d54565b601b54610446565b61047c612e3b565b610446610987366004614bc0565b612f0c565b61047c61099a366004614930565b612ffa565b61044660045481565b610446600a5481565b610446600b5481565b6104466109c836600461498f565b613158565b61047c6109db366004614be3565b61326f565b61047c6109ee366004614c2f565b613441565b61047c613601565b60606000610a07611652565b60105490915067ffffffffffffffff811115610a2557610a25614c00565b604051908082528060200260200182016040528015610a4e578160200160208202803683370190505b5073ffffffffffffffffffffffffffffffffffffffff84166000908152601e602052604090205490925015610b745760005b601054811015610b725773ffffffffffffffffffffffffffffffffffffffff84166000818152601760209081526040808320858452825280832054938352601682528083208584529091529020548351670de0b6b3a76400009190859085908110610aed57610aed614cd4565b6020026020010151610aff9190614d32565b73ffffffffffffffffffffffffffffffffffffffff87166000908152601e6020526040902054610b2f9190614d45565b610b399190614d5c565b610b439190614d97565b838281518110610b5557610b55614cd4565b602090810291909101015280610b6a81614daa565b915050610a80565b505b50919050565b600654600754600091610ba091610b918286614d45565b610b9b9190614d5c565b613631565b92915050565b60606010805480602002602001604051908101604052809291908181526020018280548015610c0b57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610be0575b5050505050905090565b60005473ffffffffffffffffffffffffffffffffffffffff163314610cc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201527f6f726d207468697320616374696f6e000000000000000000000000000000000060648201526084015b60405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229060200160405180910390a150565b60006002805403610da7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cb8565b60028055610db83380858542613649565b60016002559392505050565b60135460609067ffffffffffffffff811115610de257610de2614c00565b604051908082528060200260200182016040528015610e0b578160200160208202803683370190505b50905060005b601354811015610e615762093a80610e2882613158565b610e329190614d45565b828281518110610e4457610e44614cd4565b602090810291909101015280610e5981614daa565b915050610e11565b5090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152602460209081526040808320805482518185028101850190935280835260609492939192909184015b82821015610f0e57838290600052602060002090600502016040518060a00160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152505081526020019060010190610eaa565b505050509050919050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152601f6020526040812054600354670de0b6b3a764000091610f5591614d45565b610ba09190614d5c565b6000805473ffffffffffffffffffffffffffffffffffffffff90811690841603610f8b57506001610ba0565b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600f6020526040902054818516911603610fc457506001610ba0565b50600092915050565b60008080610fda84612412565b905073ffffffffffffffffffffffffffffffffffffffff8116156110ad576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301527f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015611084573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a89190614de2565b61115d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301527f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015611139573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115d9190614de2565b91506000670de0b6b3a76400007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111f99190614de2565b6112039190614d45565b600954600a546112139086614d45565b61121d9190614d45565b6112279190614d5c565b905060008073ffffffffffffffffffffffffffffffffffffffff8416156112565761125184611bd2565b61125f565b61125f876113cb565b905080156112b15760008161127c670de0b6b3a764000088614d45565b6112869190614d5c565b9050670de0b6b3a7640000600a548261129f9190614d45565b6112a99190614d5c565b9250506112b6565b600091505b508082116112c457806112c6565b815b9450600a548511156112d857600a5494505b50505050919050565b600280540361134c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cb8565b6002805560215462010000900460ff16156113c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f5265776172647320636f6c6c656374696f6e20706175736564000000000000006044820152606401610cb8565b506001600255565b6000670de0b6b3a7640000600b546113e28461290e565b610f559190614d45565b80156113fa576113fa613601565b73ffffffffffffffffffffffffffffffffffffffff82161561150c57600080600061142485611dd2565b9250925092506114338561399a565b73ffffffffffffffffffffffffffffffffffffffff85166000908152600c602052604090208290558281106114b757600061146e8483614d32565b905080601c5461147e9190614d97565b601c5561148b8185614d97565b73ffffffffffffffffffffffffffffffffffffffff87166000908152601e602052604090205550611508565b60006114c38285614d32565b905080601c546114d39190614d32565b601c556114e08185614d32565b73ffffffffffffffffffffffffffffffffffffffff87166000908152601e6020526040902055505b5050505b5050565b600080602360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166386fc88d36040518163ffffffff1660e01b8152600401602060405180830381865afa158015611580573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a49190614de2565b6115af906004614d45565b602360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166354f0f7d56040518163ffffffff1660e01b8152600401602060405180830381865afa15801561161c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116409190614de2565b610f5590670de0b6b3a7640000614d45565b6060601b54600014806116655750601c54155b156116bf576015805480602002602001604051908101604052809291908181526020018280548015610c0b57602002820191906000526020600020905b8154815260200190600101908083116116a2575050505050905090565b60105467ffffffffffffffff8111156116da576116da614c00565b604051908082528060200260200182016040528015611703578160200160208202803683370190505b50905060005b601554811015610e6157601c5461171f82613158565b60055461172a613a9a565b6117349190614d32565b61173e9190614d45565b61175090670de0b6b3a7640000614d45565b61175a9190614d5c565b6015828154811061176d5761176d614cd4565b90600052602060002001546117829190614d97565b82828151811061179457611794614cd4565b6020908102919091010152806117a981614daa565b915050611709565b73ffffffffffffffffffffffffffffffffffffffff821660009081526024602052604081208054829190849081106117eb576117eb614cd4565b600091825260208083206040805160a081018252600590940290910180548452600181015484840181905260028201548584015260038201546060860152600490910154608085015273ffffffffffffffffffffffffffffffffffffffff891685526018909252832054919350111561186957506020810151611891565b5073ffffffffffffffffffffffffffffffffffffffff84166000908152601860205260409020545b4282606001511161195157606082015173ffffffffffffffffffffffffffffffffffffffff861660009081526018602052604090205410156119485760008183606001516118df9190614d32565b905060008360600151426118f39190614d32565b90506000611905610441600285614d5c565b905060006119138382614d45565b61191d8584614d45565b6119279190614d97565b90506119338385614d97565b61193d9082614d5c565b9650505050506119a1565b600092506119a1565b6000808284606001516119649190614d32565b905060004285606001516119789190614d32565b905060026119868284614d97565b6119909190614d5c565b9250505061199d81610b7a565b9350505b81608001518311156119b557816080015192505b505092915050565b60606002805403611a2a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cb8565b60028055610db8338484613aad565b60246020528160005260406000208181548110611a5557600080fd5b600091825260209091206005909102018054600182015460028301546003840154600490940154929550909350919085565b60015473ffffffffffffffffffffffffffffffffffffffff163314611b2e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527f2063616e20616363657074206f776e65727368697000000000000000000000006064820152608401610cb8565b6000546001546040805173ffffffffffffffffffffffffffffffffffffffff93841681529290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a160018054600080547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff841617909155169055565b6000670de0b6b3a7640000600b546113e284610f19565b600054829073ffffffffffffffffffffffffffffffffffffffff16331480611c165750611c163382610f5f565b611c7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f74206f776e6572206f7220746b6e206d67720000000000000000000000006044820152606401610cb8565b6000805b601054811015611cf6578473ffffffffffffffffffffffffffffffffffffffff1660108281548110611cb457611cb4614cd4565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1603611ce45760019150611cf6565b80611cee81614daa565b915050611c80565b50808015611d2a575073ffffffffffffffffffffffffffffffffffffffff8481166000908152600f60205260409020541633145b80611d55575080158015611d55575060005473ffffffffffffffffffffffffffffffffffffffff1633145b15611d6b57611d65843385613d79565b50505050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4e6f2076616c696420746f6b656e7320746f207265636f7665720000000000006044820152606401610cb8565b505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152601e60205260408120549080611e0384610fcd565b73ffffffffffffffffffffffffffffffffffffffff85166000908152601d602052604081205491935090158015611e5d575073ffffffffffffffffffffffffffffffffffffffff85166000908152601e6020526040902054155b80611e8d575073ffffffffffffffffffffffffffffffffffffffff85166000908152600c60205260409020548310155b15611e99575081611ed9565b73ffffffffffffffffffffffffffffffffffffffff85166000908152600c6020526040902054600290611ecc9085614d97565b611ed69190614d5c565b90505b6000915060005b73ffffffffffffffffffffffffffffffffffffffff8616600090815260246020526040902054811015611ffd5773ffffffffffffffffffffffffffffffffffffffff86166000908152602460205260408120805483908110611f4457611f44614cd4565b90600052602060002090600502016040518060a00160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152505090506000611f9d88846117b1565b60408301519091506000670de0b6b3a7640000611fba8785614d97565b611fc49084614d45565b611fce9190614d5c565b611fd89083614d97565b9050611fe48188614d97565b9650505050508080611ff590614daa565b915050611ee0565b50509193909250565b60005473ffffffffffffffffffffffffffffffffffffffff1633148061203f5750738412ebf45bac1b340bbe8f318b928c466c4e39ca33145b6120a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4e6f74206f776e6572206f722074696d656c6f636b00000000000000000000006044820152606401610cb8565b73ffffffffffffffffffffffffffffffffffffffff166000908152600d6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b6000600354600b5461210b9190614d45565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152670de0b6b3a76400009182917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156121a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121c79190614de2565b6113e29190614d45565b600280540361223c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cb8565b6002805533600161224d82826113ec565b60008061225a3387613ee2565b9150915060008583604001516122709190614d97565b90506021546122a09065010000000000900473ffffffffffffffffffffffffffffffffffffffff163330896140a7565b6040805160a0810182528881526020858101518183015281830184905260608087015190830152608080870151908301523360009081526024909152919091208054849081106122f2576122f2614cd4565b9060005260206000209060050201600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015590505061234133876001614245565b604080518881526020810188905233917f2640b32e7e5d0fa2a21ea06b22fbd75fda0fda384a895a5fdeef43646de47a0c910160405180910390a2505060016002555050505050565b606060028054036123f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cb8565b6002805561240733836001613aad565b600160025592915050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604081205460ff1615612444575090565b5073ffffffffffffffffffffffffffffffffffffffff90811660009081526020805260409020541690565b919050565b60005473ffffffffffffffffffffffffffffffffffffffff163314806124ad5750738412ebf45bac1b340bbe8f318b928c466c4e39ca33145b612513576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4e6f74206f776e6572206f722074696d656c6f636b00000000000000000000006044820152606401610cb8565b6021805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff931515610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff951515630100000002959095167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff00ff909316929092179390931791909116179055565b6002805403612615576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cb8565b6002805533600161262682826113ec565b6000806126333387613ee2565b915091504285116126a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d75737420626520696e207468652066757475726500000000000000000000006044820152606401610cb8565b6000428360600151116126b45760006126c4565b4283606001516126c49190614d32565b905060006126d24288614d32565b905081811161273d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f43616e6e6f742073686f7274656e206c6f636b2074696d6500000000000000006044820152606401610cb8565b6008548110156127a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d696e696d756d207374616b652074696d65206e6f74206d65740000000000006044820152606401610cb8565b600754811115612815576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f547279696e6720746f206c6f636b20666f7220746f6f206c6f6e6700000000006044820152606401610cb8565b6040518060a001604052808981526020014281526020018560400151815260200188815260200161284583610b7a565b905233600090815260246020526040902080548590811061286857612868614cd4565b906000526020600020906005020160008201518160000155602082015181600101556040820151816002015560608201518160030155608082015181600401559050506128b63360006113ec565b6040805189815260208101839052428183015260608101899052905133917fc2cf1aae6decacbc52f96b4e4fec96d4ebab5236e4ed987165537bc463014a43919081900360800190a250506001600255505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152601d6020526040812054600354670de0b6b3a764000091610f5591614d45565b600054849073ffffffffffffffffffffffffffffffffffffffff1633148061297757506129773382610f5f565b6129dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f74206f776e6572206f7220746b6e206d67720000000000000000000000006044820152606401610cb8565b73ffffffffffffffffffffffffffffffffffffffff8516600090815260146020526040902054601380548692908110612a1857612a18614cd4565b9060005260206000200181905550826011601460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205481548110612a7957612a79614cd4565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055918716815260149091526040902054601280548492908110612aea57612aea614cd4565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604090205460ff16612bc8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c69642070726f7879000000000000000000000000000000000000006044820152606401610cb8565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600e6020908152604080832033845290915290205460ff16612c62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f50726f787920686173206e6f7420616c6c6f77656420796f75207965740000006044820152606401610cb8565b33600090815260208052604090205473ffffffffffffffffffffffffffffffffffffffff168015612cd757336000908152601d602090815260408083205473ffffffffffffffffffffffffffffffffffffffff85168452601f9092528220805491929091612cd1908490614d32565b90915550505b3360009081526020808052604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8716908117909155601d835281842054908452601f9092528220805491929091612d4b908490614d97565b90915550505050565b600054829073ffffffffffffffffffffffffffffffffffffffff16331480612d815750612d813382610f5f565b612de7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f74206f776e6572206f7220746b6e206d67720000000000000000000000006044820152606401610cb8565b5073ffffffffffffffffffffffffffffffffffffffff9182166000908152600f6020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001691909216179055565b60005473ffffffffffffffffffffffffffffffffffffffff16331480612e745750738412ebf45bac1b340bbe8f318b928c466c4e39ca33145b612eda576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4e6f74206f776e6572206f722074696d656c6f636b00000000000000000000006044820152606401610cb8565b602180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b60006002805403612f79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cb8565b60028055602154610100900460ff1615612fef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f5769746864726177616c732070617573656400000000000000000000000000006044820152606401610cb8565b610db83383856143b8565b336000908152600d602052604090205460ff16613073576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c69642070726f7879000000000000000000000000000000000000006044820152606401610cb8565b336000818152600e6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8681168552908352818420805460ff8116157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009091161790559180529091205416036131555773ffffffffffffffffffffffffffffffffffffffff811660009081526020808052604080832080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055601d825280832054338452601f909252822080549192909161314f908490614d32565b90915550505b50565b6000806011838154811061316e5761316e614cd4565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169050801561324957670de0b6b3a7640000601984815481106131b4576131b4614cd4565b90600052602060002001548273ffffffffffffffffffffffffffffffffffffffff16630a3be7576040518163ffffffff1660e01b8152600401602060405180830381865afa15801561320a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061322e9190614de2565b6132389190614d45565b6132429190614d5c565b9150610b74565b6013838154811061325c5761325c614cd4565b9060005260206000200154915050919050565b60005b60115481101561150c5760006011828154811061329157613291614cd4565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169050801561342e5782806132e35750601a82815481106132d5576132d5614cd4565b906000526020600020015442115b1561342e576040517f6472eee100000000000000000000000000000000000000000000000000000000815230600482015242602482015273ffffffffffffffffffffffffffffffffffffffff821690636472eee1906044016020604051808303816000875af115801561335a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061337e9190614de2565b6019838154811061339157613391614cd4565b90600052602060002001819055508073ffffffffffffffffffffffffffffffffffffffff1663513872bd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156133ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061340e9190614de2565b601a838154811061342157613421614cd4565b6000918252602090912001555b508061343981614daa565b915050613272565b60005473ffffffffffffffffffffffffffffffffffffffff1633148061347a5750738412ebf45bac1b340bbe8f318b928c466c4e39ca33145b6134e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4e6f74206f776e6572206f722074696d656c6f636b00000000000000000000006044820152606401610cb8565b8051670de0b6b3a76400001115613553576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4d757374206265203e3d204d554c2050524543000000000000000000000000006044820152606401610cb8565b608081015160011180159061356d575060a0810151600111155b6135d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4d757374206265203e3d203100000000000000000000000000000000000000006044820152606401610cb8565b80516006556020810151600a556040810151600b556060810151600955608081015160075560a00151600855565b61360b600061326f565b613613611510565b600355600454421061362957613627614566565b565b613627614899565b60008183106136405781613642565b825b9392505050565b600085600161365882826113ec565b6021546301000000900460ff16156136cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f5374616b696e67207061757365640000000000000000000000000000000000006044820152606401610cb8565b600854851015613738576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d696e696d756d207374616b652074696d65206e6f74206d65740000000000006044820152606401610cb8565b6007548511156137a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f547279696e6720746f206c6f636b20666f7220746f6f206c6f6e6700000000006044820152606401610cb8565b6021546137d29065010000000000900473ffffffffffffffffffffffffffffffffffffffff168830896140a7565b60006137dd86610b7a565b73ffffffffffffffffffffffffffffffffffffffff8a166000908152601d602090815260408083205490517fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608f901b169281019290925260348201899052605482018b9052607482015291925090609401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012073ffffffffffffffffffffffffffffffffffffffff8e1660009081526024835283902060a0850184528185529184018a90529183018b905290925090606081016138d08a8a614d97565b8152602090810185905282546001818101855560009485529382902083516005909202019081559082015181840155604082015160028201556060820151600382015560809091015160049091015561392c908b908a90614245565b604080518981526020810189905290810182905273ffffffffffffffffffffffffffffffffffffffff8a811660608301528b16907ff400e72e69ef4402819dfc57eeddc66f5eb69bf405e0e8098b1946ec1ac14a229060800160405180910390a29998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116156131555760006139c1826109fb565b905060005b8151811015613a2f578181815181106139e1576139e1614cd4565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff85166000908152601783526040808220858352909352919091205580613a2781614daa565b9150506139c6565b5060005b8151811015611dcd5760158181548110613a4f57613a4f614cd4565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff8616835260168252604080842085855290925291205580613a9281614daa565b915050613a33565b6000613aa842600454613631565b905090565b6060836001613abc82826113ec565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260186020526040902042905560215462010000900460ff1615613b57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f5265776172647320636f6c6c656374696f6e20706175736564000000000000006044820152606401610cb8565b60105467ffffffffffffffff811115613b7257613b72614c00565b604051908082528060200260200182016040528015613b9b578160200160208202803683370190505b50925060005b601054811015613d6f5773ffffffffffffffffffffffffffffffffffffffff871660009081526017602090815260408083208484529091529020548451859083908110613bf057613bf0614cd4565b60209081029190910181019190915273ffffffffffffffffffffffffffffffffffffffff881660009081526017825260408082208483529092529081208190558451859083908110613c4457613c44614cd4565b60200260200101511115613d5d57613cb360108281548110613c6857613c68614cd4565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1687868481518110613ca657613ca6614cd4565b6020026020010151613d79565b8673ffffffffffffffffffffffffffffffffffffffff167f1d2f2ca53af5d2f333bd32fdd45f9c52ad8ebe31414f7792912077fcb3876dff858381518110613cfd57613cfd614cd4565b602002602001015160108481548110613d1857613d18614cd4565b600091825260209182902001546040805193845273ffffffffffffffffffffffffffffffffffffffff918216928401929092528a169082015260600160405180910390a25b80613d6781614daa565b915050613ba1565b5050509392505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790529151600092839290871691613e109190614e1f565b6000604051808303816000865af19150503d8060008114613e4d576040519150601f19603f3d011682016040523d82523d6000602084013e613e52565b606091505b5091509150818015613e7c575080511580613e7c575080806020019051810190613e7c9190614e3b565b611508576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c4544006044820152606401610cb8565b613f176040518060a0016040528060008019168152602001600081526020016000815260200160008152602001600081525090565b6000805b73ffffffffffffffffffffffffffffffffffffffff85166000908152602460205260409020548110156140355773ffffffffffffffffffffffffffffffffffffffff85166000908152602460205260409020805482908110613f7f57613f7f614cd4565b90600052602060002090600502016000015484036140235773ffffffffffffffffffffffffffffffffffffffff85166000908152602460205260409020805482908110613fce57613fce614cd4565b90600052602060002090600502016040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815250509250809150614035565b8061402d81614daa565b915050613f1b565b50815183146140a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5374616b65206e6f7420666f756e6400000000000000000000000000000000006044820152606401610cb8565b9250929050565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905291516000928392908816916141469190614e1f565b6000604051808303816000865af19150503d8060008114614183576040519150601f19603f3d011682016040523d82523d6000602084013e614188565b606091505b50915091508180156141b25750805115806141b25750808060200190518101906141b29190614e3b565b61423d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f5472616e7366657248656c7065723a205452414e534645525f46524f4d5f464160448201527f494c4544000000000000000000000000000000000000000000000000000000006064820152608401610cb8565b505050505050565b600061425084612412565b905081156143055782601b600082825461426a9190614d97565b909155505073ffffffffffffffffffffffffffffffffffffffff84166000908152601d6020526040812080548592906142a4908490614d97565b909155505073ffffffffffffffffffffffffffffffffffffffff8116156143005773ffffffffffffffffffffffffffffffffffffffff81166000908152601f6020526040812080548592906142fa908490614d97565b90915550505b6143ad565b82601b60008282546143179190614d32565b909155505073ffffffffffffffffffffffffffffffffffffffff84166000908152601d602052604081208054859290614351908490614d32565b909155505073ffffffffffffffffffffffffffffffffffffffff8116156143ad5773ffffffffffffffffffffffffffffffffffffffff81166000908152601f6020526040812080548592906143a7908490614d32565b90915550505b611d658460006113ec565b60006143c684846001613aad565b506000806143d48685613ee2565b915091508160600151421015806143f2575060215460ff1615156001145b614458576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616b65206973207374696c6c206c6f636b656421000000000000000000006044820152606401610cb8565b6040820151801561455c576021546144909065010000000000900473ffffffffffffffffffffffffffffffffffffffff168783613d79565b73ffffffffffffffffffffffffffffffffffffffff871660009081526024602052604090208054839081106144c7576144c7614cd4565b6000918252602082206005909102018181556001810182905560028101829055600381018290556004018190556145019088908390614245565b604080518281526020810187905273ffffffffffffffffffffffffffffffffffffffff888116828401529151918916917f1d9308f6b22a2754a1c622bb30889e8f8f956c83e524d039e9d65d5f052eb9089181900360600190a25b9695505050505050565b60005b6012548110156146575760006012828154811061458857614588614cd4565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1690508015614644576040517f092193ab00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff82169063092193ab9060240160408051808303816000875af115801561461d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146419190614e58565b50505b508061464f81614daa565b915050614569565b50600062093a806004544261466c9190614d32565b6146769190614d5c565b905060005b601054811015614859576010818154811061469857614698614cd4565b6000918252602090912001546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561470f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147339190614de2565b61473e836001614d97565b62093a8061474b84613158565b6147559190614d45565b61475f9190614d45565b11156010828154811061477457614774614cd4565b60009182526020918290200154604080517f4e6f7420656e6f7567682072657761726420746f6b656e7320617661696c6162938101939093527f6c653a20000000000000000000000000000000000000000000000000000000009083015260601b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016604482015260580160405160208183030381529060405290614846576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cb89190614e7c565b508061485181614daa565b91505061467b565b5062093a80614869826001614d97565b6148739190614d45565b6004546148809190614d97565b60045561488b614899565b614893611510565b60035550565b60006148a3611652565b905060005b6015548110156148fd578181815181106148c4576148c4614cd4565b6020026020010151601582815481106148df576148df614cd4565b600091825260209091200155806148f581614daa565b9150506148a8565b50614906613a9a565b60055550565b803573ffffffffffffffffffffffffffffffffffffffff8116811461246f57600080fd5b60006020828403121561494257600080fd5b6136428261490c565b6020808252825182820181905260009190848201906040850190845b8181101561498357835183529284019291840191600101614967565b50909695505050505050565b6000602082840312156149a157600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b8181101561498357835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016149c4565b60008060408385031215614a0957600080fd5b50508035926020909101359150565b602080825282518282018190526000919060409081850190868401855b82811015614a795781518051855286810151878601528581015186860152606080820151908601526080908101519085015260a09093019290850190600101614a35565b5091979650505050505050565b60008060408385031215614a9957600080fd5b614aa28361490c565b9150614ab06020840161490c565b90509250929050565b801515811461315557600080fd5b60008060408385031215614ada57600080fd5b614ae38361490c565b91506020830135614af381614ab9565b809150509250929050565b60008060408385031215614b1157600080fd5b614b1a8361490c565b946020939093013593505050565b600080600060608486031215614b3d57600080fd5b8335614b4881614ab9565b92506020840135614b5881614ab9565b91506040840135614b6881614ab9565b809150509250925092565b60008060008060808587031215614b8957600080fd5b614b928561490c565b935060208501359250614ba76040860161490c565b9150614bb56060860161490c565b905092959194509250565b60008060408385031215614bd357600080fd5b82359150614ab06020840161490c565b600060208284031215614bf557600080fd5b813561364281614ab9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060c08284031215614c4157600080fd5b82601f830112614c5057600080fd5b60405160c0810181811067ffffffffffffffff82111715614c9a577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040528060c0840185811115614caf57600080fd5b845b81811015614cc9578035835260209283019201614cb1565b509195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610ba057610ba0614d03565b8082028115828204841417610ba057610ba0614d03565b600082614d92577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820180821115610ba057610ba0614d03565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614ddb57614ddb614d03565b5060010190565b600060208284031215614df457600080fd5b5051919050565b60005b83811015614e16578181015183820152602001614dfe565b50506000910152565b60008251614e31818460208701614dfb565b9190910192915050565b600060208284031215614e4d57600080fd5b815161364281614ab9565b60008060408385031215614e6b57600080fd5b505080516020909101519092909150565b6020815260008251806020840152614e9b816040850160208701614dfb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220838a9e12a21450aede84e9c7e1e559b8d8328c14801856b22b3efaf7e57470e764736f6c63430008110033000000000000000000000000b1748c79709f4ba2dd82834b8c82d4a505003f2700000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000081b0dcda53482a2ea9eb496342dc787643323e9500000000000000000000000000000000000000000000000000000000000000010000000000000000000000003432b6a60d23ca0dfca7761b7ab56459d9c964d00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000b1748c79709f4ba2dd82834b8c82d4a505003f27000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000a86cc92e3da000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000278dc748eda1d8efef1adfb518542612b49fcd34
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106104055760003560e01c80638980f11f1161021a578063d2fbdc0d11610135578063e44b9fa5116100c8578063f2a8d34911610097578063f77e34d11161007c578063f77e34d1146109cd578063facefb64146109e0578063fff6cae9146109f357600080fd5b8063f2a8d349146109b1578063f2caeb1e146109ba57600080fd5b8063e44b9fa514610979578063e7f305821461098c578063ebe2b12b1461099f578063f288baf6146109a857600080fd5b8063d9f96e8d11610104578063d9f96e8d14610920578063de1a655114610956578063e01f62bf14610969578063e1ba95d21461097157600080fd5b8063d2fbdc0d146108d4578063d42fc9b4146108e7578063d5e1a9c6146108fa578063d7400d561461090d57600080fd5b8063b94c4dcb116101ad578063ca6df29d1161017c578063ca6df29d14610879578063cc2abd64146108af578063cdc82e80146108c2578063d2010fb4146108cb57600080fd5b8063b94c4dcb14610841578063c00007b01461084a578063c35438261461085d578063c8f33c911461087057600080fd5b80639637927f116101e95780639637927f14610805578063a0f2347614610812578063aa1d4fce14610825578063b85efd061461082e57600080fd5b80638980f11f146107915780638bad86a7146107a45780638da5cb5b146107d257806391cf600a146107f257600080fd5b80634f39059c116103255780636e27cef9116102b85780637910d17b1161028757806379ba50971161026c57806379ba5097146107565780637d6ef08e1461075e5780637f472e541461077e57600080fd5b80637910d17b146107085780637970833e1461071b57600080fd5b80636e27cef9146106bb57806370641a36146106c457806372f702f3146106cc578063774d4ae7146106f557600080fd5b80635bfd9258116102f45780635bfd92581461066b57806364f2c06014610673578063693392451461067b5780636c430dbb1461069b57600080fd5b80634f39059c146106055780634fd2b5361461062557806353a47bb714610638578063551897731461065857600080fd5b8063218751b21161039d57806336f89af21161036c57806336f89af21461057c578063386a9525146105b2578063387edc86146105bc57806341a16f3f146105cf57600080fd5b8063218751b2146104cc578063231b68dc1461051157806328408bab146105345780632c0c2a0a1461056957600080fd5b806317b18c89116103d957806317b18c891461047e5780631c1f78eb146104915780631e090f01146104995780631face856146104b957600080fd5b80628cc2621461040a5780630d7bac4f1461043357806312edb24c146104545780631627540c14610469575b600080fd5b61041d610418366004614930565b6109fb565b60405161042a919061494b565b60405180910390f35b61044661044136600461498f565b610b7a565b60405190815260200161042a565b61045c610ba6565b60405161042a91906149a8565b61047c610477366004614930565b610c15565b005b61044661048c3660046149f6565b610d3a565b61041d610dc4565b6104ac6104a7366004614930565b610e65565b60405161042a9190614a18565b6104466104c7366004614930565b610f19565b6023546104ec9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161042a565b61052461051f366004614a86565b610f5f565b604051901515815260200161042a565b6104ec610542366004614930565b602080526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b610446610577366004614930565b610fcd565b61044661058a366004614930565b73ffffffffffffffffffffffffffffffffffffffff166000908152601e602052604090205490565b61044662093a8081565b61047c6105ca366004614930565b6112e1565b6104ec6105dd366004614930565b600f6020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b6022546104ec9073ffffffffffffffffffffffffffffffffffffffff1681565b610446610633366004614930565b6113cb565b6001546104ec9073ffffffffffffffffffffffffffffffffffffffff1681565b61047c610666366004614ac7565b6113ec565b610446611510565b601c54610446565b610446610689366004614930565b60146020526000908152604090205481565b6104466106a9366004614930565b60186020526000908152604090205481565b61044660085481565b61041d611652565b6021546104ec9065010000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b610446610703366004614afe565b6117b1565b61041d610716366004614ac7565b6119bd565b61072e610729366004614afe565b611a39565b604080519586526020860194909452928401919091526060830152608082015260a00161042a565b61047c611a87565b61044661076c366004614930565b601f6020526000908152604090205481565b61044661078c366004614930565b611bd2565b61047c61079f366004614afe565b611be9565b6107b76107b2366004614930565b611dd2565b6040805193845260208401929092529082015260600161042a565b6000546104ec9073ffffffffffffffffffffffffffffffffffffffff1681565b61047c610800366004614930565b612006565b6021546105249060ff1681565b610446610820366004614930565b6120f9565b61044660095481565b61047c61083c3660046149f6565b6121d1565b61044660075481565b61041d610858366004614930565b61238a565b6104ec61086b366004614930565b612412565b61044660055481565b610446610887366004614930565b73ffffffffffffffffffffffffffffffffffffffff1660009081526024602052604090205490565b61047c6108bd366004614b28565b612474565b61044660065481565b61044660035481565b61047c6108e23660046149f6565b6125aa565b6104466108f5366004614930565b61290e565b61047c610908366004614b73565b61294a565b61047c61091b366004614930565b612b39565b61044661092e366004614930565b73ffffffffffffffffffffffffffffffffffffffff166000908152601d602052604090205490565b61047c610964366004614a86565b612d54565b601b54610446565b61047c612e3b565b610446610987366004614bc0565b612f0c565b61047c61099a366004614930565b612ffa565b61044660045481565b610446600a5481565b610446600b5481565b6104466109c836600461498f565b613158565b61047c6109db366004614be3565b61326f565b61047c6109ee366004614c2f565b613441565b61047c613601565b60606000610a07611652565b60105490915067ffffffffffffffff811115610a2557610a25614c00565b604051908082528060200260200182016040528015610a4e578160200160208202803683370190505b5073ffffffffffffffffffffffffffffffffffffffff84166000908152601e602052604090205490925015610b745760005b601054811015610b725773ffffffffffffffffffffffffffffffffffffffff84166000818152601760209081526040808320858452825280832054938352601682528083208584529091529020548351670de0b6b3a76400009190859085908110610aed57610aed614cd4565b6020026020010151610aff9190614d32565b73ffffffffffffffffffffffffffffffffffffffff87166000908152601e6020526040902054610b2f9190614d45565b610b399190614d5c565b610b439190614d97565b838281518110610b5557610b55614cd4565b602090810291909101015280610b6a81614daa565b915050610a80565b505b50919050565b600654600754600091610ba091610b918286614d45565b610b9b9190614d5c565b613631565b92915050565b60606010805480602002602001604051908101604052809291908181526020018280548015610c0b57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610be0575b5050505050905090565b60005473ffffffffffffffffffffffffffffffffffffffff163314610cc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201527f6f726d207468697320616374696f6e000000000000000000000000000000000060648201526084015b60405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229060200160405180910390a150565b60006002805403610da7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cb8565b60028055610db83380858542613649565b60016002559392505050565b60135460609067ffffffffffffffff811115610de257610de2614c00565b604051908082528060200260200182016040528015610e0b578160200160208202803683370190505b50905060005b601354811015610e615762093a80610e2882613158565b610e329190614d45565b828281518110610e4457610e44614cd4565b602090810291909101015280610e5981614daa565b915050610e11565b5090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152602460209081526040808320805482518185028101850190935280835260609492939192909184015b82821015610f0e57838290600052602060002090600502016040518060a00160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152505081526020019060010190610eaa565b505050509050919050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152601f6020526040812054600354670de0b6b3a764000091610f5591614d45565b610ba09190614d5c565b6000805473ffffffffffffffffffffffffffffffffffffffff90811690841603610f8b57506001610ba0565b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600f6020526040902054818516911603610fc457506001610ba0565b50600092915050565b60008080610fda84612412565b905073ffffffffffffffffffffffffffffffffffffffff8116156110ad576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301527f000000000000000000000000c8418af6358ffdda74e09ca9cc3fe03ca6adc5b016906370a0823190602401602060405180830381865afa158015611084573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a89190614de2565b61115d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301527f000000000000000000000000c8418af6358ffdda74e09ca9cc3fe03ca6adc5b016906370a0823190602401602060405180830381865afa158015611139573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115d9190614de2565b91506000670de0b6b3a76400007f000000000000000000000000c8418af6358ffdda74e09ca9cc3fe03ca6adc5b073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111f99190614de2565b6112039190614d45565b600954600a546112139086614d45565b61121d9190614d45565b6112279190614d5c565b905060008073ffffffffffffffffffffffffffffffffffffffff8416156112565761125184611bd2565b61125f565b61125f876113cb565b905080156112b15760008161127c670de0b6b3a764000088614d45565b6112869190614d5c565b9050670de0b6b3a7640000600a548261129f9190614d45565b6112a99190614d5c565b9250506112b6565b600091505b508082116112c457806112c6565b815b9450600a548511156112d857600a5494505b50505050919050565b600280540361134c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cb8565b6002805560215462010000900460ff16156113c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f5265776172647320636f6c6c656374696f6e20706175736564000000000000006044820152606401610cb8565b506001600255565b6000670de0b6b3a7640000600b546113e28461290e565b610f559190614d45565b80156113fa576113fa613601565b73ffffffffffffffffffffffffffffffffffffffff82161561150c57600080600061142485611dd2565b9250925092506114338561399a565b73ffffffffffffffffffffffffffffffffffffffff85166000908152600c602052604090208290558281106114b757600061146e8483614d32565b905080601c5461147e9190614d97565b601c5561148b8185614d97565b73ffffffffffffffffffffffffffffffffffffffff87166000908152601e602052604090205550611508565b60006114c38285614d32565b905080601c546114d39190614d32565b601c556114e08185614d32565b73ffffffffffffffffffffffffffffffffffffffff87166000908152601e6020526040902055505b5050505b5050565b600080602360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166386fc88d36040518163ffffffff1660e01b8152600401602060405180830381865afa158015611580573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a49190614de2565b6115af906004614d45565b602360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166354f0f7d56040518163ffffffff1660e01b8152600401602060405180830381865afa15801561161c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116409190614de2565b610f5590670de0b6b3a7640000614d45565b6060601b54600014806116655750601c54155b156116bf576015805480602002602001604051908101604052809291908181526020018280548015610c0b57602002820191906000526020600020905b8154815260200190600101908083116116a2575050505050905090565b60105467ffffffffffffffff8111156116da576116da614c00565b604051908082528060200260200182016040528015611703578160200160208202803683370190505b50905060005b601554811015610e6157601c5461171f82613158565b60055461172a613a9a565b6117349190614d32565b61173e9190614d45565b61175090670de0b6b3a7640000614d45565b61175a9190614d5c565b6015828154811061176d5761176d614cd4565b90600052602060002001546117829190614d97565b82828151811061179457611794614cd4565b6020908102919091010152806117a981614daa565b915050611709565b73ffffffffffffffffffffffffffffffffffffffff821660009081526024602052604081208054829190849081106117eb576117eb614cd4565b600091825260208083206040805160a081018252600590940290910180548452600181015484840181905260028201548584015260038201546060860152600490910154608085015273ffffffffffffffffffffffffffffffffffffffff891685526018909252832054919350111561186957506020810151611891565b5073ffffffffffffffffffffffffffffffffffffffff84166000908152601860205260409020545b4282606001511161195157606082015173ffffffffffffffffffffffffffffffffffffffff861660009081526018602052604090205410156119485760008183606001516118df9190614d32565b905060008360600151426118f39190614d32565b90506000611905610441600285614d5c565b905060006119138382614d45565b61191d8584614d45565b6119279190614d97565b90506119338385614d97565b61193d9082614d5c565b9650505050506119a1565b600092506119a1565b6000808284606001516119649190614d32565b905060004285606001516119789190614d32565b905060026119868284614d97565b6119909190614d5c565b9250505061199d81610b7a565b9350505b81608001518311156119b557816080015192505b505092915050565b60606002805403611a2a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cb8565b60028055610db8338484613aad565b60246020528160005260406000208181548110611a5557600080fd5b600091825260209091206005909102018054600182015460028301546003840154600490940154929550909350919085565b60015473ffffffffffffffffffffffffffffffffffffffff163314611b2e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527f2063616e20616363657074206f776e65727368697000000000000000000000006064820152608401610cb8565b6000546001546040805173ffffffffffffffffffffffffffffffffffffffff93841681529290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a160018054600080547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff841617909155169055565b6000670de0b6b3a7640000600b546113e284610f19565b600054829073ffffffffffffffffffffffffffffffffffffffff16331480611c165750611c163382610f5f565b611c7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f74206f776e6572206f7220746b6e206d67720000000000000000000000006044820152606401610cb8565b6000805b601054811015611cf6578473ffffffffffffffffffffffffffffffffffffffff1660108281548110611cb457611cb4614cd4565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1603611ce45760019150611cf6565b80611cee81614daa565b915050611c80565b50808015611d2a575073ffffffffffffffffffffffffffffffffffffffff8481166000908152600f60205260409020541633145b80611d55575080158015611d55575060005473ffffffffffffffffffffffffffffffffffffffff1633145b15611d6b57611d65843385613d79565b50505050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4e6f2076616c696420746f6b656e7320746f207265636f7665720000000000006044820152606401610cb8565b505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152601e60205260408120549080611e0384610fcd565b73ffffffffffffffffffffffffffffffffffffffff85166000908152601d602052604081205491935090158015611e5d575073ffffffffffffffffffffffffffffffffffffffff85166000908152601e6020526040902054155b80611e8d575073ffffffffffffffffffffffffffffffffffffffff85166000908152600c60205260409020548310155b15611e99575081611ed9565b73ffffffffffffffffffffffffffffffffffffffff85166000908152600c6020526040902054600290611ecc9085614d97565b611ed69190614d5c565b90505b6000915060005b73ffffffffffffffffffffffffffffffffffffffff8616600090815260246020526040902054811015611ffd5773ffffffffffffffffffffffffffffffffffffffff86166000908152602460205260408120805483908110611f4457611f44614cd4565b90600052602060002090600502016040518060a00160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152505090506000611f9d88846117b1565b60408301519091506000670de0b6b3a7640000611fba8785614d97565b611fc49084614d45565b611fce9190614d5c565b611fd89083614d97565b9050611fe48188614d97565b9650505050508080611ff590614daa565b915050611ee0565b50509193909250565b60005473ffffffffffffffffffffffffffffffffffffffff1633148061203f5750738412ebf45bac1b340bbe8f318b928c466c4e39ca33145b6120a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4e6f74206f776e6572206f722074696d656c6f636b00000000000000000000006044820152606401610cb8565b73ffffffffffffffffffffffffffffffffffffffff166000908152600d6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b6000600354600b5461210b9190614d45565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152670de0b6b3a76400009182917f000000000000000000000000c8418af6358ffdda74e09ca9cc3fe03ca6adc5b016906370a0823190602401602060405180830381865afa1580156121a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121c79190614de2565b6113e29190614d45565b600280540361223c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cb8565b6002805533600161224d82826113ec565b60008061225a3387613ee2565b9150915060008583604001516122709190614d97565b90506021546122a09065010000000000900473ffffffffffffffffffffffffffffffffffffffff163330896140a7565b6040805160a0810182528881526020858101518183015281830184905260608087015190830152608080870151908301523360009081526024909152919091208054849081106122f2576122f2614cd4565b9060005260206000209060050201600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015590505061234133876001614245565b604080518881526020810188905233917f2640b32e7e5d0fa2a21ea06b22fbd75fda0fda384a895a5fdeef43646de47a0c910160405180910390a2505060016002555050505050565b606060028054036123f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cb8565b6002805561240733836001613aad565b600160025592915050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604081205460ff1615612444575090565b5073ffffffffffffffffffffffffffffffffffffffff90811660009081526020805260409020541690565b919050565b60005473ffffffffffffffffffffffffffffffffffffffff163314806124ad5750738412ebf45bac1b340bbe8f318b928c466c4e39ca33145b612513576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4e6f74206f776e6572206f722074696d656c6f636b00000000000000000000006044820152606401610cb8565b6021805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff931515610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff951515630100000002959095167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff00ff909316929092179390931791909116179055565b6002805403612615576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cb8565b6002805533600161262682826113ec565b6000806126333387613ee2565b915091504285116126a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d75737420626520696e207468652066757475726500000000000000000000006044820152606401610cb8565b6000428360600151116126b45760006126c4565b4283606001516126c49190614d32565b905060006126d24288614d32565b905081811161273d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f43616e6e6f742073686f7274656e206c6f636b2074696d6500000000000000006044820152606401610cb8565b6008548110156127a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d696e696d756d207374616b652074696d65206e6f74206d65740000000000006044820152606401610cb8565b600754811115612815576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f547279696e6720746f206c6f636b20666f7220746f6f206c6f6e6700000000006044820152606401610cb8565b6040518060a001604052808981526020014281526020018560400151815260200188815260200161284583610b7a565b905233600090815260246020526040902080548590811061286857612868614cd4565b906000526020600020906005020160008201518160000155602082015181600101556040820151816002015560608201518160030155608082015181600401559050506128b63360006113ec565b6040805189815260208101839052428183015260608101899052905133917fc2cf1aae6decacbc52f96b4e4fec96d4ebab5236e4ed987165537bc463014a43919081900360800190a250506001600255505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152601d6020526040812054600354670de0b6b3a764000091610f5591614d45565b600054849073ffffffffffffffffffffffffffffffffffffffff1633148061297757506129773382610f5f565b6129dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f74206f776e6572206f7220746b6e206d67720000000000000000000000006044820152606401610cb8565b73ffffffffffffffffffffffffffffffffffffffff8516600090815260146020526040902054601380548692908110612a1857612a18614cd4565b9060005260206000200181905550826011601460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205481548110612a7957612a79614cd4565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055918716815260149091526040902054601280548492908110612aea57612aea614cd4565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604090205460ff16612bc8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c69642070726f7879000000000000000000000000000000000000006044820152606401610cb8565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600e6020908152604080832033845290915290205460ff16612c62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f50726f787920686173206e6f7420616c6c6f77656420796f75207965740000006044820152606401610cb8565b33600090815260208052604090205473ffffffffffffffffffffffffffffffffffffffff168015612cd757336000908152601d602090815260408083205473ffffffffffffffffffffffffffffffffffffffff85168452601f9092528220805491929091612cd1908490614d32565b90915550505b3360009081526020808052604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8716908117909155601d835281842054908452601f9092528220805491929091612d4b908490614d97565b90915550505050565b600054829073ffffffffffffffffffffffffffffffffffffffff16331480612d815750612d813382610f5f565b612de7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f74206f776e6572206f7220746b6e206d67720000000000000000000000006044820152606401610cb8565b5073ffffffffffffffffffffffffffffffffffffffff9182166000908152600f6020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001691909216179055565b60005473ffffffffffffffffffffffffffffffffffffffff16331480612e745750738412ebf45bac1b340bbe8f318b928c466c4e39ca33145b612eda576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4e6f74206f776e6572206f722074696d656c6f636b00000000000000000000006044820152606401610cb8565b602180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b60006002805403612f79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cb8565b60028055602154610100900460ff1615612fef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f5769746864726177616c732070617573656400000000000000000000000000006044820152606401610cb8565b610db83383856143b8565b336000908152600d602052604090205460ff16613073576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c69642070726f7879000000000000000000000000000000000000006044820152606401610cb8565b336000818152600e6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8681168552908352818420805460ff8116157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009091161790559180529091205416036131555773ffffffffffffffffffffffffffffffffffffffff811660009081526020808052604080832080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055601d825280832054338452601f909252822080549192909161314f908490614d32565b90915550505b50565b6000806011838154811061316e5761316e614cd4565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169050801561324957670de0b6b3a7640000601984815481106131b4576131b4614cd4565b90600052602060002001548273ffffffffffffffffffffffffffffffffffffffff16630a3be7576040518163ffffffff1660e01b8152600401602060405180830381865afa15801561320a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061322e9190614de2565b6132389190614d45565b6132429190614d5c565b9150610b74565b6013838154811061325c5761325c614cd4565b9060005260206000200154915050919050565b60005b60115481101561150c5760006011828154811061329157613291614cd4565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169050801561342e5782806132e35750601a82815481106132d5576132d5614cd4565b906000526020600020015442115b1561342e576040517f6472eee100000000000000000000000000000000000000000000000000000000815230600482015242602482015273ffffffffffffffffffffffffffffffffffffffff821690636472eee1906044016020604051808303816000875af115801561335a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061337e9190614de2565b6019838154811061339157613391614cd4565b90600052602060002001819055508073ffffffffffffffffffffffffffffffffffffffff1663513872bd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156133ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061340e9190614de2565b601a838154811061342157613421614cd4565b6000918252602090912001555b508061343981614daa565b915050613272565b60005473ffffffffffffffffffffffffffffffffffffffff1633148061347a5750738412ebf45bac1b340bbe8f318b928c466c4e39ca33145b6134e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4e6f74206f776e6572206f722074696d656c6f636b00000000000000000000006044820152606401610cb8565b8051670de0b6b3a76400001115613553576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4d757374206265203e3d204d554c2050524543000000000000000000000000006044820152606401610cb8565b608081015160011180159061356d575060a0810151600111155b6135d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4d757374206265203e3d203100000000000000000000000000000000000000006044820152606401610cb8565b80516006556020810151600a556040810151600b556060810151600955608081015160075560a00151600855565b61360b600061326f565b613613611510565b600355600454421061362957613627614566565b565b613627614899565b60008183106136405781613642565b825b9392505050565b600085600161365882826113ec565b6021546301000000900460ff16156136cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f5374616b696e67207061757365640000000000000000000000000000000000006044820152606401610cb8565b600854851015613738576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d696e696d756d207374616b652074696d65206e6f74206d65740000000000006044820152606401610cb8565b6007548511156137a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f547279696e6720746f206c6f636b20666f7220746f6f206c6f6e6700000000006044820152606401610cb8565b6021546137d29065010000000000900473ffffffffffffffffffffffffffffffffffffffff168830896140a7565b60006137dd86610b7a565b73ffffffffffffffffffffffffffffffffffffffff8a166000908152601d602090815260408083205490517fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608f901b169281019290925260348201899052605482018b9052607482015291925090609401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012073ffffffffffffffffffffffffffffffffffffffff8e1660009081526024835283902060a0850184528185529184018a90529183018b905290925090606081016138d08a8a614d97565b8152602090810185905282546001818101855560009485529382902083516005909202019081559082015181840155604082015160028201556060820151600382015560809091015160049091015561392c908b908a90614245565b604080518981526020810189905290810182905273ffffffffffffffffffffffffffffffffffffffff8a811660608301528b16907ff400e72e69ef4402819dfc57eeddc66f5eb69bf405e0e8098b1946ec1ac14a229060800160405180910390a29998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116156131555760006139c1826109fb565b905060005b8151811015613a2f578181815181106139e1576139e1614cd4565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff85166000908152601783526040808220858352909352919091205580613a2781614daa565b9150506139c6565b5060005b8151811015611dcd5760158181548110613a4f57613a4f614cd4565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff8616835260168252604080842085855290925291205580613a9281614daa565b915050613a33565b6000613aa842600454613631565b905090565b6060836001613abc82826113ec565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260186020526040902042905560215462010000900460ff1615613b57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f5265776172647320636f6c6c656374696f6e20706175736564000000000000006044820152606401610cb8565b60105467ffffffffffffffff811115613b7257613b72614c00565b604051908082528060200260200182016040528015613b9b578160200160208202803683370190505b50925060005b601054811015613d6f5773ffffffffffffffffffffffffffffffffffffffff871660009081526017602090815260408083208484529091529020548451859083908110613bf057613bf0614cd4565b60209081029190910181019190915273ffffffffffffffffffffffffffffffffffffffff881660009081526017825260408082208483529092529081208190558451859083908110613c4457613c44614cd4565b60200260200101511115613d5d57613cb360108281548110613c6857613c68614cd4565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1687868481518110613ca657613ca6614cd4565b6020026020010151613d79565b8673ffffffffffffffffffffffffffffffffffffffff167f1d2f2ca53af5d2f333bd32fdd45f9c52ad8ebe31414f7792912077fcb3876dff858381518110613cfd57613cfd614cd4565b602002602001015160108481548110613d1857613d18614cd4565b600091825260209182902001546040805193845273ffffffffffffffffffffffffffffffffffffffff918216928401929092528a169082015260600160405180910390a25b80613d6781614daa565b915050613ba1565b5050509392505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790529151600092839290871691613e109190614e1f565b6000604051808303816000865af19150503d8060008114613e4d576040519150601f19603f3d011682016040523d82523d6000602084013e613e52565b606091505b5091509150818015613e7c575080511580613e7c575080806020019051810190613e7c9190614e3b565b611508576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c4544006044820152606401610cb8565b613f176040518060a0016040528060008019168152602001600081526020016000815260200160008152602001600081525090565b6000805b73ffffffffffffffffffffffffffffffffffffffff85166000908152602460205260409020548110156140355773ffffffffffffffffffffffffffffffffffffffff85166000908152602460205260409020805482908110613f7f57613f7f614cd4565b90600052602060002090600502016000015484036140235773ffffffffffffffffffffffffffffffffffffffff85166000908152602460205260409020805482908110613fce57613fce614cd4565b90600052602060002090600502016040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815250509250809150614035565b8061402d81614daa565b915050613f1b565b50815183146140a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5374616b65206e6f7420666f756e6400000000000000000000000000000000006044820152606401610cb8565b9250929050565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905291516000928392908816916141469190614e1f565b6000604051808303816000865af19150503d8060008114614183576040519150601f19603f3d011682016040523d82523d6000602084013e614188565b606091505b50915091508180156141b25750805115806141b25750808060200190518101906141b29190614e3b565b61423d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f5472616e7366657248656c7065723a205452414e534645525f46524f4d5f464160448201527f494c4544000000000000000000000000000000000000000000000000000000006064820152608401610cb8565b505050505050565b600061425084612412565b905081156143055782601b600082825461426a9190614d97565b909155505073ffffffffffffffffffffffffffffffffffffffff84166000908152601d6020526040812080548592906142a4908490614d97565b909155505073ffffffffffffffffffffffffffffffffffffffff8116156143005773ffffffffffffffffffffffffffffffffffffffff81166000908152601f6020526040812080548592906142fa908490614d97565b90915550505b6143ad565b82601b60008282546143179190614d32565b909155505073ffffffffffffffffffffffffffffffffffffffff84166000908152601d602052604081208054859290614351908490614d32565b909155505073ffffffffffffffffffffffffffffffffffffffff8116156143ad5773ffffffffffffffffffffffffffffffffffffffff81166000908152601f6020526040812080548592906143a7908490614d32565b90915550505b611d658460006113ec565b60006143c684846001613aad565b506000806143d48685613ee2565b915091508160600151421015806143f2575060215460ff1615156001145b614458576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616b65206973207374696c6c206c6f636b656421000000000000000000006044820152606401610cb8565b6040820151801561455c576021546144909065010000000000900473ffffffffffffffffffffffffffffffffffffffff168783613d79565b73ffffffffffffffffffffffffffffffffffffffff871660009081526024602052604090208054839081106144c7576144c7614cd4565b6000918252602082206005909102018181556001810182905560028101829055600381018290556004018190556145019088908390614245565b604080518281526020810187905273ffffffffffffffffffffffffffffffffffffffff888116828401529151918916917f1d9308f6b22a2754a1c622bb30889e8f8f956c83e524d039e9d65d5f052eb9089181900360600190a25b9695505050505050565b60005b6012548110156146575760006012828154811061458857614588614cd4565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1690508015614644576040517f092193ab00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff82169063092193ab9060240160408051808303816000875af115801561461d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146419190614e58565b50505b508061464f81614daa565b915050614569565b50600062093a806004544261466c9190614d32565b6146769190614d5c565b905060005b601054811015614859576010818154811061469857614698614cd4565b6000918252602090912001546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561470f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147339190614de2565b61473e836001614d97565b62093a8061474b84613158565b6147559190614d45565b61475f9190614d45565b11156010828154811061477457614774614cd4565b60009182526020918290200154604080517f4e6f7420656e6f7567682072657761726420746f6b656e7320617661696c6162938101939093527f6c653a20000000000000000000000000000000000000000000000000000000009083015260601b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016604482015260580160405160208183030381529060405290614846576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cb89190614e7c565b508061485181614daa565b91505061467b565b5062093a80614869826001614d97565b6148739190614d45565b6004546148809190614d97565b60045561488b614899565b614893611510565b60035550565b60006148a3611652565b905060005b6015548110156148fd578181815181106148c4576148c4614cd4565b6020026020010151601582815481106148df576148df614cd4565b600091825260209091200155806148f581614daa565b9150506148a8565b50614906613a9a565b60055550565b803573ffffffffffffffffffffffffffffffffffffffff8116811461246f57600080fd5b60006020828403121561494257600080fd5b6136428261490c565b6020808252825182820181905260009190848201906040850190845b8181101561498357835183529284019291840191600101614967565b50909695505050505050565b6000602082840312156149a157600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b8181101561498357835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016149c4565b60008060408385031215614a0957600080fd5b50508035926020909101359150565b602080825282518282018190526000919060409081850190868401855b82811015614a795781518051855286810151878601528581015186860152606080820151908601526080908101519085015260a09093019290850190600101614a35565b5091979650505050505050565b60008060408385031215614a9957600080fd5b614aa28361490c565b9150614ab06020840161490c565b90509250929050565b801515811461315557600080fd5b60008060408385031215614ada57600080fd5b614ae38361490c565b91506020830135614af381614ab9565b809150509250929050565b60008060408385031215614b1157600080fd5b614b1a8361490c565b946020939093013593505050565b600080600060608486031215614b3d57600080fd5b8335614b4881614ab9565b92506020840135614b5881614ab9565b91506040840135614b6881614ab9565b809150509250925092565b60008060008060808587031215614b8957600080fd5b614b928561490c565b935060208501359250614ba76040860161490c565b9150614bb56060860161490c565b905092959194509250565b60008060408385031215614bd357600080fd5b82359150614ab06020840161490c565b600060208284031215614bf557600080fd5b813561364281614ab9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060c08284031215614c4157600080fd5b82601f830112614c5057600080fd5b60405160c0810181811067ffffffffffffffff82111715614c9a577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040528060c0840185811115614caf57600080fd5b845b81811015614cc9578035835260209283019201614cb1565b509195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610ba057610ba0614d03565b8082028115828204841417610ba057610ba0614d03565b600082614d92577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820180821115610ba057610ba0614d03565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614ddb57614ddb614d03565b5060010190565b600060208284031215614df457600080fd5b5051919050565b60005b83811015614e16578181015183820152602001614dfe565b50506000910152565b60008251614e31818460208701614dfb565b9190910192915050565b600060208284031215614e4d57600080fd5b815161364281614ab9565b60008060408385031215614e6b57600080fd5b505080516020909101519092909150565b6020815260008251806020840152614e9b816040850160208701614dfb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220838a9e12a21450aede84e9c7e1e559b8d8328c14801856b22b3efaf7e57470e764736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000b1748c79709f4ba2dd82834b8c82d4a505003f2700000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000081b0dcda53482a2ea9eb496342dc787643323e9500000000000000000000000000000000000000000000000000000000000000010000000000000000000000003432b6a60d23ca0dfca7761b7ab56459d9c964d00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000b1748c79709f4ba2dd82834b8c82d4a505003f27000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000a86cc92e3da000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000278dc748eda1d8efef1adfb518542612b49fcd34
-----Decoded View---------------
Arg [0] : _owner (address): 0xB1748C79709f4Ba2Dd82834B8c82D4a505003f27
Arg [1] : _rewardTokens (address[]): 0x3432B6A60D23Ca0dFCa7761B7ab56459D9C964D0
Arg [2] : _rewardManagers (address[]): 0xB1748C79709f4Ba2Dd82834B8c82D4a505003f27
Arg [3] : _rewardRates (uint256[]): 11574074074074
Arg [4] : _gaugeControllers (address[]): 0x0000000000000000000000000000000000000000
Arg [5] : _rewardDistributors (address[]): 0x278dC748edA1d8eFEf1aDFB518542612b49Fcd34
Arg [6] : _stakingToken (address): 0x81b0dCDa53482A2EA9eb496342dC787643323e95
-----Encoded View---------------
17 Constructor Arguments found :
Arg [0] : 000000000000000000000000b1748c79709f4ba2dd82834b8c82d4a505003f27
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [4] : 00000000000000000000000000000000000000000000000000000000000001a0
Arg [5] : 00000000000000000000000000000000000000000000000000000000000001e0
Arg [6] : 00000000000000000000000081b0dcda53482a2ea9eb496342dc787643323e95
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [8] : 0000000000000000000000003432b6a60d23ca0dfca7761b7ab56459d9c964d0
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [10] : 000000000000000000000000b1748c79709f4ba2dd82834b8c82d4a505003f27
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [12] : 00000000000000000000000000000000000000000000000000000a86cc92e3da
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [14] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [15] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [16] : 000000000000000000000000278dc748eda1d8efef1adfb518542612b49fcd34
Deployed Bytecode Sourcemap
87801:1604:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44022:529;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46232:477;;;;;;:::i;:::-;;:::i;:::-;;;1374:25:1;;;1362:2;1347:18;46232:477:0;1228:177:1;42301:109:0;;;:::i;:::-;;;;;;;:::i;29821:141::-;;;;;;:::i;:::-;;:::i;:::-;;83479:190;;;;;;:::i;:::-;;:::i;44615:339::-;;;:::i;78175:133::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;46928:179::-;;;;;;:::i;:::-;;:::i;67727:23::-;;;;;;;;;;;;3737:42:1;3725:55;;;3707:74;;3695:2;3680:18;67727:23:0;3547:240:1;41965:298:0;;;;;;:::i;:::-;;:::i;:::-;;;4222:14:1;;4215:22;4197:41;;4185:2;4170:18;41965:298:0;4057:187:1;39341:60:0;;;;;;:::i;:::-;;;;;;;;;;;;;;;;48476:1752;;;;;;:::i;:::-;;:::i;45668:127::-;;;;;;:::i;:::-;45761:26;;45734:7;45761:26;;;:17;:26;;;;;;;45668:127;38281:48;;38323:6;38281:48;;54343:238;;;;;;:::i;:::-;;:::i;37909:49::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;67691:29;;;;;;;;;47628:181;;;;;;:::i;:::-;;:::i;29589:29::-;;;;;;;;;52177:1522;;;;;;:::i;:::-;;:::i;88772:630::-;;;:::i;45382:111::-;45463:22;;45382:111;;38162:55;;;;;;:::i;:::-;;;;;;;;;;;;;;38673:54;;;;;;:::i;:::-;;;;;;;;;;;;;;37183:37;;;;;;43125:681;;;:::i;67639:45::-;;;;;;;;;;;;73366:2692;;;;;;:::i;:::-;;:::i;55050:206::-;;;;;;:::i;:::-;;:::i;68390:53::-;;;;;;:::i;:::-;;:::i;:::-;;;;5956:25:1;;;6012:2;5997:18;;5990:34;;;;6040:18;;;6033:34;;;;6098:2;6083:18;;6076:34;6141:3;6126:19;;6119:35;5943:3;5928:19;68390:53:0;5697:463:1;29970:271:0;;;:::i;39132:52::-;;;;;;:::i;:::-;;;;;;;;;;;;;;47817:199;;;;;;:::i;:::-;;:::i;62048:1013::-;;;;;;:::i;:::-;;:::i;76119:1961::-;;;;;;:::i;:::-;;:::i;:::-;;;;6367:25:1;;;6423:2;6408:18;;6401:34;;;;6451:18;;;6444:34;6355:2;6340:18;76119:1961:0;6165:319:1;29562:20:0;;;;;;;;;61758:161;;;;;;:::i;:::-;;:::i;39532:26::-;;;;;;;;;47210:224;;;;;;:::i;:::-;;:::i;37277:55::-;;;;;;80927:1006;;;;;;:::i;:::-;;:::i;37028:62::-;;;;;;54870:172;;;;;;:::i;:::-;;:::i;48024:444::-;;;;;;:::i;:::-;;:::i;36874:29::-;;;;;;78384:133;;;;;;:::i;:::-;78481:21;;78454:7;78481:21;;;:12;:21;;;;;:28;;78384:133;61208:311;;;;;;:::i;:::-;;:::i;36954:50::-;;;;;;36677:30;;;;;;81987:1357;;;;;;:::i;:::-;;:::i;46754:166::-;;;;;;:::i;:::-;;:::i;64104:483::-;;;;;;:::i;:::-;;:::i;51211:800::-;;;;;;:::i;:::-;;:::i;45216:128::-;;;;;;:::i;:::-;45310:26;;45283:7;45310:26;;;:17;:26;;;;;;;45216:128;64662:207;;;;;;:::i;:::-;;:::i;45052:113::-;45134:23;;45052:113;;61612:97;;;:::i;85395:259::-;;;;;;:::i;:::-;;:::i;50486:610::-;;;;;;:::i;:::-;;:::i;36840:27::-;;;;;;37415:51;;;;;;37491:59;;;;;;42603:452;;;;;;:::i;:::-;;:::i;59898:761::-;;;;;;:::i;:::-;;:::i;63069:958::-;;;;;;:::i;:::-;;:::i;60667:363::-;;;:::i;44022:529::-;44076:27;44116;44146:17;:15;:17::i;:::-;44201:12;:19;44116:47;;-1:-1:-1;44187:34:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44187:34:0;-1:-1:-1;44238:26:0;;;44267:1;44238:26;;;:17;:26;;;;;;44174:47;;-1:-1:-1;44238:30:0;44234:310;;44289:9;44284:249;44308:12;:19;44304:23;;44284:249;;;44498:16;;;;;;;:7;:16;;;;;;;;:19;;;;;;;;;44417:32;;;:23;:32;;;;;:35;;;;;;;;;44401:13;;44457:4;;44417:35;44401:10;;44515:1;;44401:13;;;;;;:::i;:::-;;;;;;;:51;;;;:::i;:::-;44371:26;;;;;;;:17;:26;;;;;;:82;;;;:::i;:::-;44370:91;;;;:::i;:::-;44369:148;;;;:::i;:::-;44353:10;44364:1;44353:13;;;;;;;;:::i;:::-;;;;;;;;;;:164;44329:3;;;;:::i;:::-;;;;44284:249;;;;44234:310;44105:446;44022:529;;;:::o;46232:477::-;46596:19;;46661:28;;46291:7;;46573:127;;46631:26;46596:19;46631:4;:26;:::i;:::-;46630:59;;;;:::i;:::-;46573:8;:127::i;:::-;46566:134;46232:477;-1:-1:-1;;46232:477:0:o;42301:109::-;42354:16;42390:12;42383:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42301:109;:::o;29821:141::-;30301:5;;;;30287:10;:19;30279:79;;;;;;;10775:2:1;30279:79:0;;;10757:21:1;10814:2;10794:18;;;10787:30;10853:34;10833:18;;;10826:62;10924:17;10904:18;;;10897:45;10959:19;;30279:79:0;;;;;;;;;29893:14:::1;:23:::0;;;::::1;;::::0;::::1;::::0;;::::1;::::0;;;29932:22:::1;::::0;3707:74:1;;;29932:22:0::1;::::0;3695:2:1;3680:18;29932:22:0::1;;;;;;;29821:141:::0;:::o;83479:190::-;83564:7;33736:1;34342:7;;:19;34334:63;;;;;;;11191:2:1;34334:63:0;;;11173:21:1;11230:2;11210:18;;;11203:30;11269:33;11249:18;;;11242:61;11320:18;;34334:63:0;10989:355:1;34334:63:0;33736:1;34475:18;;83591:70:::1;83604:10;::::0;83628:9;83639:4;83645:15:::1;83591:12;:70::i;:::-;33692:1:::0;34654:7;:22;83584:77;83479:190;-1:-1:-1;;;83479:190:0:o;44615:339::-;44765:17;:24;44670:41;;44751:39;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44751:39:0;;44724:66;;44808:9;44803:144;44827:17;:24;44823:28;;44803:144;;;38323:6;44903:14;44915:1;44903:11;:14::i;:::-;:32;;;;:::i;:::-;44873:24;44898:1;44873:27;;;;;;;;:::i;:::-;;;;;;;;;;:62;44853:3;;;;:::i;:::-;;;;44803:144;;;;44615:339;:::o;78175:133::-;78279:21;;;;;;;:12;:21;;;;;;;;78272:28;;;;;;;;;;;;;;;;;78239:20;;78272:28;;78279:21;;78272:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78175:133;;;:::o;46928:179::-;47043:32;;;46997:7;47043:32;;;:17;:32;;;;;;47025:15;;36805:4;;47025:50;;;:::i;:::-;47024:75;;;;:::i;41965:298::-;42061:4;42096:5;;;;;;42081:20;;;;42077:136;;-1:-1:-1;42110:4:0;42103:11;;42077:136;42152:48;:33;;;;;;;:14;:33;;;;;;:48;;;:33;;:48;42148:65;;-1:-1:-1;42209:4:0;42202:11;;42148:65;-1:-1:-1;42249:5:0;41965:298;;;;:::o;48476:1752::-;48539:24;;;48700:20;48712:7;48700:11;:20::i;:::-;48680:40;-1:-1:-1;48751:23:0;;;;48750:81;;48805:26;;;;;:15;3725:55:1;;;48805:26:0;;;3707:74:1;48805:5:0;:15;;;;3680:18:1;;48805:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48750:81;;;48778:24;;;;;:15;3725:55:1;;;48778:24:0;;;3707:74:1;48778:5:0;:15;;;;3680:18:1;;48778:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48731:100;;48937:19;36805:4;49061:5;:17;;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:42;;;;:::i;:::-;49002:24;;48979:20;;48960:39;;:16;:39;:::i;:::-;:66;;;;:::i;:::-;48959:145;;;;:::i;:::-;48937:167;-1:-1:-1;49213:19:0;;49428:23;;;;49427:94;;49486:35;49511:9;49486:24;:35::i;:::-;49427:94;;;49455:28;49475:7;49455:19;:28::i;:::-;49398:123;-1:-1:-1;49542:30:0;;49538:323;;49593:27;49667:26;49624:39;36805:4;49624:16;:39;:::i;:::-;49623:70;;;;:::i;:::-;49593:100;;36805:4;49767:20;;49745:19;:42;;;;:::i;:::-;49744:67;;;;:::i;:::-;49730:81;;49573:254;49538:323;;;49860:1;49846:15;;49538:323;49243:699;50029:11;50015;:25;:53;;50057:11;50015:53;;;50043:11;50015:53;49995:74;;50159:20;;50140:16;:39;50136:84;;;50200:20;;50181:39;;50136:84;48565:1663;;;;48476:1752;;;:::o;54343:238::-;33736:1;34342:7;;:19;34334:63;;;;;;;11191:2:1;34334:63:0;;;11173:21:1;11230:2;11210:18;;;11203:30;11269:33;11249:18;;;11242:61;11320:18;;34334:63:0;10989:355:1;34334:63:0;33736:1;34475:18;;54440:23:::1;::::0;;;::::1;;;:32;54432:70;;;::::0;::::1;::::0;;11740:2:1;54432:70:0::1;::::0;::::1;11722:21:1::0;11779:2;11759:18;;;11752:30;11818:27;11798:18;;;11791:55;11863:18;;54432:70:0::1;11538:349:1::0;54432:70:0::1;-1:-1:-1::0;33692:1:0;34654:7;:22;54343:238::o;47628:181::-;47695:7;36805:4;47749:28;;47723:23;47738:7;47723:14;:23::i;:::-;:54;;;;:::i;52177:1522::-;52364:8;52360:46;;;52388:6;:4;:6::i;:::-;52430:21;;;;52426:1266;;52644:27;52690:28;52737:27;52782:30;52804:7;52782:21;:30::i;:::-;52622:190;;;;;;52874:20;52886:7;52874:11;:20::i;:::-;52970:31;;;;;;;:22;:31;;;;;:54;;;53111:42;;;53107:572;;53174:19;53196:41;53218:19;53196;:41;:::i;:::-;53174:63;;53306:11;53281:22;;:36;;;;:::i;:::-;53256:22;:61;53365:33;53387:11;53365:19;:33;:::i;:::-;53336:26;;;;;;;:17;:26;;;;;:62;-1:-1:-1;53107:572:0;;;53439:19;53461:41;53483:19;53461;:41;:::i;:::-;53439:63;;53571:11;53546:22;;:36;;;;:::i;:::-;53521:22;:61;53630:33;53652:11;53630:19;:33;:::i;:::-;53601:26;;;;;;;:17;:26;;;;;:62;-1:-1:-1;53107:572:0;52453:1239;;;52426:1266;52177:1522;;:::o;88772:630::-;88828:7;88991:25;89320:9;;;;;;;;;;;:22;;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;89316:28;;:1;:28;:::i;:::-;89282:9;;;;;;;;;;;:18;;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:29;;89306:4;89282:29;:::i;43125:681::-;43173:41;43231:23;;43258:1;43231:28;:59;;;-1:-1:-1;43263:22:0;;:27;43231:59;43227:572;;;43314:21;43307:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43125:681;:::o;43227:572::-;43418:12;:19;43404:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43404:34:0;;43377:61;;43458:9;43453:289;43477:21;:28;43473:32;;43453:289;;;43685:22;;43660:14;43672:1;43660:11;:14::i;:::-;43642;;43613:26;:24;:26::i;:::-;:43;;;;:::i;:::-;43612:62;;;;:::i;:::-;:69;;43677:4;43612:69;:::i;:::-;43611:96;;;;:::i;:::-;43561:21;43583:1;43561:24;;;;;;;;:::i;:::-;;;;;;;;;:165;;;;:::i;:::-;43531:24;43556:1;43531:27;;;;;;;;:::i;:::-;;;;;;;;;;:195;43507:3;;;;:::i;:::-;;;;43453:289;;73366:2692;73557:21;;;73455:32;73557:21;;;:12;:21;;;;;:32;;73455;;73557:21;73579:9;;73557:32;;;;;;:::i;:::-;;;;;;;;;73526:63;;;;;;;;73557:32;;;;;;;73526:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73772:28;;;;;:19;:28;;;;;;73526:63;;-1:-1:-1;;73768:224:0;;;-1:-1:-1;73865:25:0;;;;73768:224;;;-1:-1:-1;73952:28:0;;;;;;;:19;:28;;;;;;73768:224;74081:15;74051:9;:26;;;:45;74047:1802;;74276:26;;;;74245:28;;;;;;;:19;:28;;;;;;:57;74241:1087;;;74322:26;74380:17;74351:9;:26;;;:46;;;;:::i;:::-;74322:75;;74416:25;74462:9;:26;;;74444:15;:44;;;;:::i;:::-;74416:72;-1:-1:-1;74568:33:0;74604:38;74619:22;74640:1;74619:18;:22;:::i;74604:38::-;74568:74;-1:-1:-1;74859:17:0;74931:21;74935:17;74859;74931:21;:::i;:::-;74880:46;74908:18;74880:25;:46;:::i;:::-;74879:74;;;;:::i;:::-;74859:94;-1:-1:-1;75012:38:0;75033:17;75012:18;:38;:::i;:::-;74999:52;;:9;:52;:::i;:::-;74972:79;;74303:764;;;;74047:1802;;74241:1087;75311:1;75284:28;;74047:1802;;;75473:21;75528:20;75580:17;75551:9;:26;;;:46;;;;:::i;:::-;75528:69;;75616:20;75668:15;75639:9;:26;;;:44;;;;:::i;:::-;75616:67;-1:-1:-1;75750:1:0;75719:27;75616:67;75719:12;:27;:::i;:::-;75718:33;;;;:::i;:::-;75702:49;;75509:258;;75808:29;75823:13;75808:14;:29::i;:::-;75781:56;;75393:456;74047:1802;75971:9;:25;;;75944:24;:52;75940:110;;;76025:9;:25;;;75998:52;;75940:110;73489:2569;;73366:2692;;;;:::o;55050:206::-;55152:16;33736:1;34342:7;;:19;34334:63;;;;;;;11191:2:1;34334:63:0;;;11173:21:1;11230:2;11210:18;;;11203:30;11269:33;11249:18;;;11242:61;11320:18;;34334:63:0;10989:355:1;34334:63:0;33736:1;34475:18;;55188:60:::1;55199:10;55211:19:::0;55232:15;55188:10:::1;:60::i;68390:53::-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68390:53:0;;-1:-1:-1;68390:53:0;;;:::o;29970:271::-;30039:14;;;;30025:10;:28;30017:94;;;;;;;12094:2:1;30017:94:0;;;12076:21:1;12133:2;12113:18;;;12106:30;12172:34;12152:18;;;12145:62;12243:23;12223:18;;;12216:51;12284:19;;30017:94:0;11892:417:1;30017:94:0;30140:5;;;30147:14;30127:35;;;30140:5;;;;12549:34:1;;30147:14:0;;;;12614:2:1;12599:18;;12592:43;30127:35:0;;12461:18:1;30127:35:0;;;;;;;30181:14;;;;30173:22;;;;;;30181:14;;;30173:22;;;;30206:27;;;29970:271::o;47817:199::-;47895:7;36805:4;47956:28;;47923:30;47939:13;47923:15;:30::i;62048:1013::-;40159:5;;62134:12;;40159:5;;40145:10;:19;;:74;;;40168:51;40186:10;40198:20;40168:17;:51::i;:::-;40137:107;;;;;;;12848:2:1;40137:107:0;;;12830:21:1;12887:2;12867:18;;;12860:30;12926:22;12906:18;;;12899:50;12966:18;;40137:107:0;12646:344:1;40137:107:0;62216:18:::1;62258:9:::0;62253:192:::1;62277:12;:19:::0;62273:23;::::1;62253:192;;;62341:12;62322:31;;:12;62335:1;62322:15;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;::::1;;:31:::0;62318:116:::1;;62390:4;62374:20;;62413:5;;62318:116;62298:3:::0;::::1;::::0;::::1;:::i;:::-;;;;62253:192;;;;62671:13;:59;;;;-1:-1:-1::0;62688:42:0::1;:28:::0;;::::1;;::::0;;;:14:::1;:28;::::0;;;;;::::1;62720:10;62688:42;62671:59;62670:123;;;;62754:13;62753:14;:39;;;;-1:-1:-1::0;62786:5:0::1;::::0;::::1;;62772:10;:19;62753:39;62648:406;;;62824:66;62852:12;62866:10;62878:11;62824:27;:66::i;:::-;62905:7;62048:1013:::0;;;:::o;62648:406::-:1;63006:36;::::0;::::1;::::0;;13197:2:1;63006:36:0::1;::::0;::::1;13179:21:1::0;13236:2;13216:18;;;13209:30;13275:28;13255:18;;;13248:56;13321:18;;63006:36:0::1;12995:350:1::0;40255:1:0::1;62048:1013:::0;;;:::o;76119:1961::-;76422:26;;;76220:27;76422:26;;;:17;:26;;;;;;;76220:27;76609:24;76440:7;76609:15;:24::i;:::-;76709:26;;;76646:33;76709:26;;;:17;:26;;;;;;76586:47;;-1:-1:-1;76646:33:0;76709:31;:66;;;;-1:-1:-1;76744:26:0;;;;;;;:17;:26;;;;;;:31;76709:66;76708:143;;;-1:-1:-1;76819:31:0;;;;;;;:22;:31;;;;;;76795:55;;;76708:143;76690:638;;;-1:-1:-1;77092:20:0;76690:638;;;77280:31;;;;;;;:22;:31;;;;;;77315:1;;77257:54;;:20;:54;:::i;:::-;77256:60;;;;:::i;:::-;77228:88;;76690:638;77463:1;77441:23;;77480:9;77475:598;77499:21;;;;;;;:12;:21;;;;;:28;77495:32;;77475:598;;;77580:21;;;77549:28;77580:21;;;:12;:21;;;;;:24;;77602:1;;77580:24;;;;;;:::i;:::-;;;;;;;;;;;77549:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77676:32;77711:34;77734:7;77743:1;77711:22;:34::i;:::-;77827:19;;;;77676:69;;-1:-1:-1;77807:17:0;36805:4;77922:52;77949:25;77676:69;77922:52;:::i;:::-;77909:66;;:9;:66;:::i;:::-;77908:91;;;;:::i;:::-;77895:105;;:9;:105;:::i;:::-;77861:139;-1:-1:-1;78015:46:0;77861:139;78015:46;;:::i;:::-;;;77534:539;;;;77529:3;;;;;:::i;:::-;;;;77475:598;;;;76349:1731;76119:1961;;;;;:::o;61758:161::-;39956:5;;;;39942:10;:19;;:79;;-1:-1:-1;39979:42:0;39965:10;:56;39942:79;39934:113;;;;;;;13552:2:1;39934:113:0;;;13534:21:1;13591:2;13571:18;;;13564:30;13630:23;13610:18;;;13603:51;13671:18;;39934:113:0;13350:345:1;39934:113:0;61879:32:::1;;;::::0;;;:19:::1;:32;::::0;;;;;;61843:68;;::::1;61879:32;::::0;;::::1;61878:33;61843:68;::::0;;61758:161::o;47210:224::-;47276:7;47410:15;;47379:28;;:46;;;;:::i;:::-;47304:24;;;;;:15;3725:55:1;;;47304:24:0;;;3707:74:1;36805:4:0;;;;47304:5;:15;;;;3680:18:1;;47304:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:47;;;;:::i;80927:1006::-;33736:1;34342:7;;:19;34334:63;;;;;;;11191:2:1;34334:63:0;;;11173:21:1;11230:2;11210:18;;;11203:30;11269:33;11249:18;;;11242:61;11320:18;;34334:63:0;10989:355:1;34334:63:0;33736:1;34475:18;;81024:10:::1;81036:4;40350:41;81024:10:::0;81036:4;40350:22:::1;:41::i;:::-;81101:28:::2;81131:21:::0;81156:29:::2;81166:10;81178:6;81156:9;:29::i;:::-;81100:85;;;;81235:15;81275:8;81253:9;:19;;;:30;;;;:::i;:::-;81235:48:::0;-1:-1:-1;81454:12:0::2;::::0;81414:91:::2;::::0;81454:12;;::::2;;;81469:10;81489:4;81496:8:::0;81414:31:::2;:91::i;:::-;81589:186;::::0;;::::2;::::0;::::2;::::0;;;;;::::2;81636:25:::0;;::::2;::::0;81589:186;;::::2;::::0;;;;;;;;81698:26;;::::2;::::0;81589:186;;;;;81739:25;;::::2;::::0;81589:186;;;;81560:10:::2;-1:-1:-1::0;81547:24:0;;;:12:::2;:24:::0;;;;;;;:39;;81572:13;;81547:39;::::2;;;;;:::i;:::-;;;;;;;;;;;:228;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81819:42;81834:10;81846:8;81856:4;81819:14;:42::i;:::-;81879:46;::::0;;14219:25:1;;;14275:2;14260:18;;14253:34;;;81896:10:0::2;::::0;81879:46:::2;::::0;14192:18:1;81879:46:0::2;;;;;;;-1:-1:-1::0;;33692:1:0;34654:7;:22;-1:-1:-1;;;;;80927:1006:0:o;54870:172::-;54949:16;33736:1;34342:7;;:19;34334:63;;;;;;;11191:2:1;34334:63:0;;;11173:21:1;11230:2;11210:18;;;11203:30;11269:33;11249:18;;;11242:61;11320:18;;34334:63:0;10989:355:1;34334:63:0;33736:1;34475:18;;54985:49:::1;54996:10;55008:19:::0;55029:4:::1;54985:10;:49::i;:::-;33692:1:::0;34654:7;:22;54978:56;54870:172;-1:-1:-1;;54870:172:0:o;48024:444::-;48103:25;;;48080:7;48103:25;;;:19;:25;;;;;;;;48099:362;;;-1:-1:-1;48306:4:0;48024:444::o;48099:362::-;-1:-1:-1;48418:31:0;;;;;;;;:25;:31;;;;;;;;48024:444::o;48099:362::-;48024:444;;;:::o;61208:311::-;39956:5;;;;39942:10;:19;;:79;;-1:-1:-1;39979:42:0;39965:10;:56;39942:79;39934:113;;;;;;;13552:2:1;39934:113:0;;;13534:21:1;13591:2;13571:18;;;13564:30;13630:23;13610:18;;;13603:51;13671:18;;39934:113:0;13350:345:1;39934:113:0;61371:13:::1;:30:::0;;61461:50;::::1;;::::0;::::1;::::0;61412:38;::::1;;61371:30;61412:38;::::0;61371:30;::::1;;::::0;::::1;61412:38:::0;;;;;;;;;;;;;;;::::1;61461:50:::0;;;::::1;;::::0;;61208:311::o;81987:1357::-;33736:1;34342:7;;:19;34334:63;;;;;;;11191:2:1;34334:63:0;;;11173:21:1;11230:2;11210:18;;;11203:30;11269:33;11249:18;;;11242:61;11320:18;;34334:63:0;10989:355:1;34334:63:0;33736:1;34475:18;;82085:10:::1;82097:4;40350:41;82085:10:::0;82097:4;40350:22:::1;:41::i;:::-;82162:28:::2;82192:21:::0;82217:29:::2;82227:10;82239:6;82217:9;:29::i;:::-;82161:85;;;;82301:15;82285:13;:31;82277:65;;;::::0;::::2;::::0;;14500:2:1;82277:65:0::2;::::0;::::2;14482:21:1::0;14539:2;14519:18;;;14512:30;14578:23;14558:18;;;14551:51;14619:18;;82277:65:0::2;14298:345:1::0;82277:65:0::2;82388:17;82438:15;82409:9;:26;;;:44;82408:97;;82504:1;82408:97;;;82486:15;82457:9;:26;;;:44;;;;:::i;:::-;82388:117:::0;-1:-1:-1;82516:16:0::2;82535:31;82551:15;82535:13:::0;:31:::2;:::i;:::-;82516:50;;82672:9;82661:8;:20;82653:57;;;::::0;::::2;::::0;;14850:2:1;82653:57:0::2;::::0;::::2;14832:21:1::0;14889:2;14869:18;;;14862:30;14928:26;14908:18;;;14901:54;14972:18;;82653:57:0::2;14648:348:1::0;82653:57:0::2;82741:13;;82729:8;:25;;82721:64;;;::::0;::::2;::::0;;15203:2:1;82721:64:0::2;::::0;::::2;15185:21:1::0;15242:2;15222:18;;;15215:30;15281:28;15261:18;;;15254:56;15327:18;;82721:64:0::2;15001:350:1::0;82721:64:0::2;82816:28;;82804:8;:40;;82796:80;;;::::0;::::2;::::0;;15558:2:1;82796:80:0::2;::::0;::::2;15540:21:1::0;15597:2;15577:18;;;15570:30;15636:29;15616:18;;;15609:57;15683:18;;82796:80:0::2;15356:351:1::0;82796:80:0::2;82960:174;;;;;;;;82986:6;82960:174;;;;83007:15;82960:174;;;;83037:9;:19;;;82960:174;;;;83071:13;82960:174;;;;83099:24;83114:8;83099:14;:24::i;:::-;82960:174:::0;;82931:10:::2;82918:24;::::0;;;:12:::2;:24;::::0;;;;:39;;82943:13;;82918:39;::::2;;;;;:::i;:::-;;;;;;;;;;;:216;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83203:41;83226:10;83238:5;83203:22;:41::i;:::-;83262:74;::::0;;15943:25:1;;;15999:2;15984:18;;15977:34;;;83305:15:0::2;16027:18:1::0;;;16020:34;16085:2;16070:18;;16063:34;;;83262:74:0;;83275:10:::2;::::0;83262:74:::2;::::0;;;;;15930:3:1;83262:74:0;;::::2;-1:-1:-1::0;;33692:1:0;34654:7;:22;-1:-1:-1;;;;;;81987:1357:0:o;46754:166::-;46862:26;;;46816:7;46862:26;;;:17;:26;;;;;;46844:15;;36805:4;;46844:44;;;:::i;64104:483::-;40159:5;;64270:20;;40159:5;;40145:10;:19;;:74;;;40168:51;40186:10;40198:20;40168:17;:51::i;:::-;40137:107;;;;;;;12848:2:1;40137:107:0;;;12830:21:1;12887:2;12867:18;;;12860:30;12926:22;12906:18;;;12899:50;12966:18;;40137:107:0;12646:344:1;40137:107:0;64321:42:::1;::::0;::::1;;::::0;;;:20:::1;:42;::::0;;;;;64303:17:::1;:61:::0;;64367:9;;64321:42;64303:61;::::1;;;;;:::i;:::-;;;;;;;;:73;;;;64450:25;64387:16;64404:20;:42;64425:20;64404:42;;;;;;;;;;;;;;;;64387:60;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;;;::::1;:88:::0;;;::::1;;::::0;;::::1;;::::0;;64505:42;;::::1;::::0;;:20:::1;:42:::0;;;;;;;64486:18:::1;:62:::0;;64551:28;;64505:42;64486:62;::::1;;;;;:::i;:::-;;;;;;;;;:93;;;;;;;;;;;;;;;;;;64104:483:::0;;;;;:::o;51211:800::-;51291:34;;;;;;;:19;:34;;;;;;;;51283:60;;;;;;;16310:2:1;51283:60:0;;;16292:21:1;16349:2;16329:18;;;16322:30;16388:15;16368:18;;;16361:43;16421:18;;51283:60:0;16108:337:1;51283:60:0;51362:36;;;;;;;:21;:36;;;;;;;;51399:10;51362:48;;;;;;;;;;51354:90;;;;;;;16652:2:1;51354:90:0;;;16634:21:1;16691:2;16671:18;;;16664:30;16730:31;16710:18;;;16703:59;16779:18;;51354:90:0;16450:353:1;51354:90:0;51590:10;51539:22;51564:37;;;:25;:37;;;;;;;;51616:28;;51612:182;;51771:10;51753:29;;;;:17;:29;;;;;;;;;;51716:33;;;;:17;:33;;;;;:66;;51753:29;;51716:33;;:66;;51753:29;;51716:66;:::i;:::-;;;;-1:-1:-1;;51612:182:0;51862:10;51836:37;;;;:25;:37;;;;;;;:53;;;;:37;:53;;;;;;;;51974:17;:29;;;;;;51938:32;;;:17;:32;;;;;:65;;51974:29;;51938:32;;:65;;51974:29;;51938:65;:::i;:::-;;;;-1:-1:-1;;;;51211:800:0:o;64662:207::-;40159:5;;64770:20;;40159:5;;40145:10;:19;;:74;;;40168:51;40186:10;40198:20;40168:17;:51::i;:::-;40137:107;;;;;;;12848:2:1;40137:107:0;;;12830:21:1;12887:2;12867:18;;;12860:30;12926:22;12906:18;;;12899:50;12966:18;;40137:107:0;12646:344:1;40137:107:0;-1:-1:-1;64803:36:0::1;::::0;;::::1;;::::0;;;:14:::1;:36;::::0;;;;:58;;;::::1;::::0;;;::::1;;::::0;;64662:207::o;61612:97::-;39956:5;;;;39942:10;:19;;:79;;-1:-1:-1;39979:42:0;39965:10;:56;39942:79;39934:113;;;;;;;13552:2:1;39934:113:0;;;13534:21:1;13591:2;13571:18;;;13564:30;13630:23;13610:18;;;13603:51;13671:18;;39934:113:0;13350:345:1;39934:113:0;61687:14:::1;::::0;;61669:32;;::::1;61687:14;::::0;;::::1;61686:15;61669:32;::::0;;61612:97::o;85395:259::-;85495:7;33736:1;34342:7;;:19;34334:63;;;;;;;11191:2:1;34334:63:0;;;11173:21:1;11230:2;11210:18;;;11203:30;11269:33;11249:18;;;11242:61;11320:18;;34334:63:0;10989:355:1;34334:63:0;33736:1;34475:18;;85523:17:::1;::::0;::::1;::::0;::::1;;;:26;85515:57;;;::::0;::::1;::::0;;17010:2:1;85515:57:0::1;::::0;::::1;16992:21:1::0;17049:2;17029:18;;;17022:30;17088:20;17068:18;;;17061:48;17126:18;;85515:57:0::1;16808:342:1::0;85515:57:0::1;85590:56;85606:10;85618:19;85639:6;85590:15;:56::i;50486:610::-:0;50585:10;50565:31;;;;:19;:31;;;;;;;;50557:57;;;;;;;16310:2:1;50557:57:0;;;16292:21:1;16349:2;16329:18;;;16322:30;16388:15;16368:18;;;16361:43;16421:18;;50557:57:0;16108:337:1;50557:57:0;50700:10;50678:33;;;;:21;:33;;;;;;;;;:49;;;;;;;;;;;;;;;;50677:50;50625:102;;;;;;;50830:41;;;;;;;;:55;50826:263;;50901:41;;;50953:1;50901:41;;;:25;:41;;;;;;;:54;;;;;;51044:17;:33;;;;;;51029:10;51011:29;;:17;:29;;;;;:66;;51044:33;;51011:29;;:66;;51044:33;;51011:66;:::i;:::-;;;;-1:-1:-1;;50826:263:0;50486:610;:::o;42603:452::-;42664:16;42693:32;42728:16;42745:9;42728:27;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;42770:38:0;;42766:282;;42951:4;42909:27;42937:9;42909:38;;;;;;;;:::i;:::-;;;;;;;;;42858:24;42837:67;;;:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:110;;;;:::i;:::-;42836:119;;;;:::i;:::-;42825:130;;42766:282;;;43008:17;43026:9;43008:28;;;;;;;;:::i;:::-;;;;;;;;;42997:39;;42682:373;42603:452;;;:::o;59898:761::-;60015:9;60010:642;60034:16;:23;60030:27;;60010:642;;;60079:32;60114:16;60131:1;60114:19;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;60152:38:0;;60148:493;;60215:12;:61;;;;60250:22;60273:1;60250:25;;;;;;;;:::i;:::-;;;;;;;;;60232:15;:43;60215:61;60211:415;;;60390:106;;;;;60473:4;60390:106;;;17329:74:1;60480:15:0;17419:18:1;;;17412:34;60390:74:0;;;;;;17302:18:1;;60390:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60357:27;60385:1;60357:30;;;;;;;;:::i;:::-;;;;;;;;:139;;;;60568:24;60547:57;;;:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60519:22;60542:1;60519:25;;;;;;;;:::i;:::-;;;;;;;;;;:87;60211:415;-1:-1:-1;60059:3:0;;;;:::i;:::-;;;;60010:642;;63069:958;39956:5;;;;39942:10;:19;;:79;;-1:-1:-1;39979:42:0;39965:10;:56;39942:79;39934:113;;;;;;;13552:2:1;39934:113:0;;;13534:21:1;13591:2;13571:18;;;13564:30;13630:23;13610:18;;;13603:51;13671:18;;39934:113:0;13350:345:1;39934:113:0;63478:13;;36805:4:::1;-1:-1:-1::0;63478:37:0::1;63470:69;;;::::0;::::1;::::0;;17659:2:1;63470:69:0::1;::::0;::::1;17641:21:1::0;17698:2;17678:18;;;17671:30;17737:21;17717:18;;;17710:49;17776:18;;63470:69:0::1;17457:343:1::0;63470:69:0::1;63663:13:::0;;::::1;::::0;63680:1:::1;-1:-1:-1::0;63663:18:0;::::1;::::0;63662:44:::1;;-1:-1:-1::0;63687:13:0;;::::1;::::0;63704:1:::1;-1:-1:-1::0;63687:18:0::1;63662:44;63654:69;;;::::0;::::1;::::0;;18348:2:1;63654:69:0::1;::::0;::::1;18330:21:1::0;18387:2;18367:18;;;18360:30;18426:14;18406:18;;;18399:42;18458:18;;63654:69:0::1;18146:336:1::0;63654:69:0::1;63758:13:::0;;63736:19:::1;:35:::0;63758:13:::1;63805::::0;::::1;::::0;63782:20:::1;:36:::0;63860:13;;::::1;::::0;63829:28:::1;:44:::0;63911:13;;::::1;::::0;63884:24:::1;:40:::0;63966:13;;::::1;::::0;63935:28:::1;:44:::0;64006:13;::::1;::::0;63990::::1;:29:::0;63069:958::o;60667:363::-;60750:25;60769:5;60750:18;:25::i;:::-;60845:16;:14;:16::i;:::-;60827:15;:34;60897:12;;60878:15;:31;60874:149;;60926:14;:12;:14::i;:::-;60667:363::o;60874:149::-;60982:29;:27;:29::i;26231:106::-;26289:7;26320:1;26316;:5;:13;;26328:1;26316:13;;;26324:1;26316:13;26309:20;26231:106;-1:-1:-1;;;26231:106:0:o;83865:1358::-;84111:7;84080:14;84096:4;40350:41;40373:7;40382:8;40350:22;:41::i;:::-;84139:13:::1;::::0;;;::::1;;;:22;84131:49;;;::::0;::::1;::::0;;18689:2:1;84131:49:0::1;::::0;::::1;18671:21:1::0;18728:2;18708:18;;;18701:30;18767:16;18747:18;;;18740:44;18801:18;;84131:49:0::1;18487:338:1::0;84131:49:0::1;84207:13;;84199:4;:21;;84191:60;;;::::0;::::1;::::0;;15203:2:1;84191:60:0::1;::::0;::::1;15185:21:1::0;15242:2;15222:18;;;15215:30;15281:28;15261:18;;;15254:56;15327:18;;84191:60:0::1;15001:350:1::0;84191:60:0::1;84278:28;;84270:4;:36;;84262:75;;;::::0;::::1;::::0;;15558:2:1;84262:75:0::1;::::0;::::1;15540:21:1::0;15597:2;15577:18;;;15570:30;15636:29;15616:18;;;15609:57;15683:18;;84262:75:0::1;15356:351:1::0;84262:75:0::1;84460:12;::::0;84420:96:::1;::::0;84460:12;;::::1;;;84475:14:::0;84499:4:::1;84506:9:::0;84420:31:::1;:96::i;:::-;84576:23;84602:20;84617:4;84602:14;:20::i;:::-;84721:33;::::0;::::1;84633:14;84721:33:::0;;;:17:::1;:33;::::0;;;;;;;;84660:95;;19076:66:1;19063:2;19059:15;;;19055:88;84660:95:0;;::::1;19043:101:1::0;;;;19160:12;;;19153:28;;;19197:12;;;19190:28;;;19234:12;;;19227:28;84576:46:0;;-1:-1:-1;84633:14:0;19271:13:1;;84660:95:0::1;::::0;;;;;::::1;::::0;;;;;;84650:106;;84660:95:::1;84650:106:::0;;::::1;::::0;84813:28:::1;::::0;::::1;;::::0;;;:12:::1;:28:::0;;;;;84847:164:::1;::::0;::::1;::::0;;;;;;;::::1;::::0;;;;;;;;;84650:106;;-1:-1:-1;84813:28:0;84847:164;;;84948:22:::1;84966:4:::0;84894:15;84948:22:::1;:::i;:::-;84847:164:::0;;::::1;::::0;;::::1;::::0;;;84813:199;;::::1;::::0;;::::1;::::0;;-1:-1:-1;84813:199:0;;;;;;;;;::::1;::::0;;::::1;;::::0;;;;;::::1;::::0;;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;;::::1;::::0;85056:47:::1;::::0;85071:14;;85087:9;;85056:14:::1;:47::i;:::-;85121:68;::::0;;19526:25:1;;;19582:2;19567:18;;19560:34;;;19610:18;;;19603:34;;;85121:68:0::1;19673:55:1::0;;;19668:2;19653:18;;19646:83;85121:68:0;::::1;::::0;::::1;::::0;19513:3:1;19498:19;85121:68:0::1;;;;;;;85209:6:::0;83865:1358;-1:-1:-1;;;;;;;;;83865:1358:0:o;53707:585::-;53769:21;;;;53765:520;;53846:27;53876:15;53883:7;53876:6;:15::i;:::-;53846:45;;53954:9;53949:118;53973:10;:17;53969:1;:21;53949:118;;;54038:10;54049:1;54038:13;;;;;;;;:::i;:::-;;;;;;;;;;;;54016:16;;;;;;;:7;:16;;;;;;:19;;;;;;;;;;:35;54033:1;53992:3;54033:1;53992:3;:::i;:::-;;;;53949:118;;;;54134:9;54129:145;54153:10;:17;54149:1;:21;54129:145;;;54234:21;54256:1;54234:24;;;;;;;;:::i;:::-;;;;;;;;;;;;;54196:32;;;;;:23;:32;;;;;;:35;;;;;;;;:62;54229:1;54172:3;54229:1;54172:3;:::i;:::-;;;;54129:145;;42462:133;42521:7;42548:39;42557:15;42574:12;;42548:8;:39::i;:::-;42541:46;;42462:133;:::o;55352:1194::-;55500:31;55475:8;55485:4;40350:41;40373:7;40382:8;40350:22;:41::i;:::-;55630:29:::1;::::0;::::1;;::::0;;;:19:::1;:29;::::0;;;;55662:15:::1;55630:47:::0;;55760:23:::1;::::0;;;::::1;;;:32;55752:70;;;::::0;::::1;::::0;;11740:2:1;55752:70:0::1;::::0;::::1;11722:21:1::0;11779:2;11759:18;;;11752:30;11818:27;11798:18;;;11791:55;11863:18;;55752:70:0::1;11538:349:1::0;55752:70:0::1;55934:12;:19:::0;55920:34:::1;::::0;::::1;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;55920:34:0::1;;55903:51;;55972:9;55967:419;55991:12;:19:::0;55987:23;::::1;55967:419;;;56052:17;::::0;::::1;;::::0;;;:7:::1;:17;::::0;;;;;;;:20;;;;;;;;;56032:17;;:14;;56070:1;;56032:17;::::1;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;:40;;;;56087:17:::1;::::0;::::1;56110:1;56087:17:::0;;;:7:::1;:17:::0;;;;;;:20;;;;;;;;;:24;;;56130:17;;:14;;56105:1;;56130:17;::::1;;;;;:::i;:::-;;;;;;;:21;56126:249;;;56172:84;56200:12;56213:1;56200:15;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;56217:19;56238:14;56253:1;56238:17;;;;;;;;:::i;:::-;;;;;;;56172:27;:84::i;:::-;56293:8;56282:77;;;56303:14;56318:1;56303:17;;;;;;;;:::i;:::-;;;;;;;56322:12;56335:1;56322:15;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;::::1;::::0;56282:77:::1;::::0;;19942:25:1;;;56322:15:0::1;::::0;;::::1;20044:18:1::0;;;20037:43;;;;20116:15;;20096:18;;;20089:43;19930:2;19915:18;56282:77:0::1;;;;;;;56126:249;56012:3:::0;::::1;::::0;::::1;:::i;:::-;;;;55967:419;;;;55352:1194:::0;;;;;;;:::o;31053:361::-;31248:45;;;31237:10;17347:55:1;;;31248:45:0;;;17329:74:1;17419:18;;;;17412:34;;;31248:45:0;;;;;;;;;;17302:18:1;;;;31248:45:0;;;;;;;;;;;;;31237:57;;-1:-1:-1;;;;31237:10:0;;;;:57;;31248:45;31237:57;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31201:93;;;;31313:7;:57;;;;-1:-1:-1;31325:11:0;;:16;;:44;;;31356:4;31345:24;;;;;;;;;;;;:::i;:::-;31305:101;;;;;;;21142:2:1;31305:101:0;;;21124:21:1;21181:2;21161:18;;;21154:30;21220:33;21200:18;;;21193:61;21271:18;;31305:101:0;20940:355:1;80356:508:0;80438:31;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80438:31:0;80471:15;;80499:280;80523:28;;;;;;;:12;:28;;;;;:35;80519:39;;80499:280;;;80594:28;;;;;;;:12;:28;;;;;:31;;80623:1;;80594:31;;;;;;:::i;:::-;;;;;;;;;;;:38;;;80584:6;:48;80580:188;;80667:28;;;;;;;:12;:28;;;;;:31;;80696:1;;80667:31;;;;;;:::i;:::-;;;;;;;;;;;80652:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80727:1;80717:11;;80747:5;;80580:188;80560:3;;;;:::i;:::-;;;;80499:280;;;-1:-1:-1;80797:19:0;;:29;;80789:57;;;;;;;21502:2:1;80789:57:0;;;21484:21:1;21541:2;21521:18;;;21514:30;21580:17;21560:18;;;21553:45;21615:18;;80789:57:0;21300:339:1;80789:57:0;80356:508;;;;;:::o;31422:402::-;31647:51;;;31636:10;21925:15:1;;;31647:51:0;;;21907:34:1;21977:15;;;21957:18;;;21950:43;22009:18;;;;22002:34;;;31647:51:0;;;;;;;;;;21819:18:1;;;;31647:51:0;;;;;;;;;;;;;31636:63;;-1:-1:-1;;;;31636:10:0;;;;:63;;31647:51;31636:63;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31600:99;;;;31718:7;:57;;;;-1:-1:-1;31730:11:0;;:16;;:44;;;31761:4;31750:24;;;;;;;;;;;;:::i;:::-;31710:106;;;;;;;22249:2:1;31710:106:0;;;22231:21:1;22288:2;22268:18;;;22261:30;22327:34;22307:18;;;22300:62;22398:6;22378:18;;;22371:34;22422:19;;31710:106:0;22047:400:1;31710:106:0;31510:314;;31422:402;;;;:::o;79478:870::-;79606:17;79626:27;79638:14;79626:11;:27::i;:::-;79606:47;;79670:6;79666:561;;;79761:3;79734:23;;:30;;;;;;;:::i;:::-;;;;-1:-1:-1;;79779:33:0;;;;;;;:17;:33;;;;;:40;;79816:3;;79779:33;:40;;79816:3;;79779:40;:::i;:::-;;;;-1:-1:-1;;79873:23:0;;;;79869:64;;79898:28;;;;;;;:17;:28;;;;;:35;;79930:3;;79898:28;:35;;79930:3;;79898:35;:::i;:::-;;;;-1:-1:-1;;79869:64:0;79666:561;;;80043:3;80016:23;;:30;;;;;;;:::i;:::-;;;;-1:-1:-1;;80061:33:0;;;;;;;:17;:33;;;;;:40;;80098:3;;80061:33;:40;;80098:3;;80061:40;:::i;:::-;;;;-1:-1:-1;;80155:23:0;;;;80151:64;;80180:28;;;;;;;:17;:28;;;;;:35;;80212:3;;80180:28;:35;;80212:3;;80180:35;:::i;:::-;;;;-1:-1:-1;;80151:64:0;80295:45;80318:14;80334:5;80295:22;:45::i;85789:1189::-;85935:7;86018:53;86029:14;86045:19;86066:4;86018:10;:53::i;:::-;;86125:28;86155:21;86180:33;86190:14;86206:6;86180:9;:33::i;:::-;86124:89;;;;86251:9;:26;;;86232:15;:45;;:71;;;-1:-1:-1;86281:14:0;;;;:22;;:14;:22;86232:71;86224:106;;;;;;;22654:2:1;86224:106:0;;;22636:21:1;22693:2;22673:18;;;22666:30;22732:24;22712:18;;;22705:52;22774:18;;86224:106:0;22452:346:1;86224:106:0;86361:19;;;;86397:13;;86393:549;;86577:12;;86541:82;;86577:12;;;;;86592:19;86613:9;86541:27;:82::i;:::-;86695:28;;;;;;;:12;:28;;;;;:43;;86724:13;;86695:43;;;;;;:::i;:::-;;;;;;;;;;;;;86688:50;;;;;;;;;;;;;;;;;;;;;;;;;;86790:48;;86805:14;;86821:9;;86790:14;:48::i;:::-;86860:70;;;23005:25:1;;;23061:2;23046:18;;23039:34;;;86860:70:0;23109:55:1;;;23089:18;;;23082:83;86860:70:0;;;;;;;;;;;22993:2:1;86860:70:0;;;86393:549;86961:9;85789:1189;-1:-1:-1;;;;;;85789:1189:0:o;56633:2814::-;56754:9;56749:327;56773:18;:25;56769:29;;56749:327;;;56820:34;56857:18;56876:1;56857:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;56897:40:0;;56893:172;;56958:91;;;;;57043:4;56958:91;;;3707:74:1;56958:76:0;;;;;;3680:18:1;;56958:91:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;56893:172;-1:-1:-1;56800:3:0;;;;:::i;:::-;;;;56749:327;;;;57436:27;38323:6;57492:12;;57474:15;:30;;;;:::i;:::-;57466:57;;;;:::i;:::-;57436:87;;57662:9;57657:284;57681:12;:19;57677:23;;57657:284;;;57803:12;57816:1;57803:15;;;;;;;;:::i;:::-;;;;;;;;;;;57796:48;;;;;57838:4;57796:48;;;3707:74:1;57803:15:0;;;;;57796:33;;3680:18:1;;57796:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;57767:23;:19;57789:1;57767:23;:::i;:::-;38323:6;57731:14;57743:1;57731:11;:14::i;:::-;:32;;;;:::i;:::-;:60;;;;:::i;:::-;57730:114;;57910:12;57923:1;57910:15;;;;;;;;:::i;:::-;;;;;;;;;;;;57853:73;;;23668:34:1;57853:73:0;;;23656:47:1;;;;23733:6;23719:12;;;23712:28;23778:2;23774:15;;;23756:12;;;23749:110;23875:12;;57853:73:0;;;;;;;;;;;;57722:207;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;57702:3:0;;;;:::i;:::-;;;;57657:284;;;-1:-1:-1;38323:6:0;58153:23;:19;58175:1;58153:23;:::i;:::-;58152:43;;;;:::i;:::-;58136:12;;:60;;;;:::i;:::-;58121:12;:75;58249:29;:27;:29::i;:::-;58348:16;:14;:16::i;:::-;58330:15;:34;-1:-1:-1;56633:2814:0:o;59455:435::-;59542:34;59579:17;:15;:17::i;:::-;59542:54;;59659:9;59654:133;59678:21;:28;59674:32;;59654:133;;;59755:17;59773:1;59755:20;;;;;;;;:::i;:::-;;;;;;;59728:21;59750:1;59728:24;;;;;;;;:::i;:::-;;;;;;;;;;:47;59708:3;;;;:::i;:::-;;;;59654:133;;;;59856:26;:24;:26::i;:::-;59839:14;:43;-1:-1:-1;59455:435:0:o;14:196:1:-;82:20;;142:42;131:54;;121:65;;111:93;;200:1;197;190:12;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;406:632::-;577:2;629:21;;;699:13;;602:18;;;721:22;;;548:4;;577:2;800:15;;;;774:2;759:18;;;548:4;843:169;857:6;854:1;851:13;843:169;;;918:13;;906:26;;987:15;;;;952:12;;;;879:1;872:9;843:169;;;-1:-1:-1;1029:3:1;;406:632;-1:-1:-1;;;;;;406:632:1:o;1043:180::-;1102:6;1155:2;1143:9;1134:7;1130:23;1126:32;1123:52;;;1171:1;1168;1161:12;1123:52;-1:-1:-1;1194:23:1;;1043:180;-1:-1:-1;1043:180:1:o;1410:681::-;1581:2;1633:21;;;1703:13;;1606:18;;;1725:22;;;1552:4;;1581:2;1804:15;;;;1778:2;1763:18;;;1552:4;1847:218;1861:6;1858:1;1855:13;1847:218;;;1926:13;;1941:42;1922:62;1910:75;;2040:15;;;;2005:12;;;;1883:1;1876:9;1847:218;;2096:248;2164:6;2172;2225:2;2213:9;2204:7;2200:23;2196:32;2193:52;;;2241:1;2238;2231:12;2193:52;-1:-1:-1;;2264:23:1;;;2334:2;2319:18;;;2306:32;;-1:-1:-1;2096:248:1:o;2531:1011::-;2760:2;2812:21;;;2882:13;;2785:18;;;2904:22;;;2731:4;;2760:2;2945;;2963:18;;;;3004:15;;;2731:4;3047:469;3061:6;3058:1;3055:13;3047:469;;;3120:13;;3158:9;;3146:22;;3208:11;;;3202:18;3188:12;;;3181:40;3261:11;;;3255:18;3241:12;;;3234:40;3297:4;3341:11;;;3335:18;3321:12;;;3314:40;3377:4;3421:11;;;3415:18;3401:12;;;3394:40;3463:4;3454:14;;;;3491:15;;;;3083:1;3076:9;3047:469;;;-1:-1:-1;3533:3:1;;2531:1011;-1:-1:-1;;;;;;;2531:1011:1:o;3792:260::-;3860:6;3868;3921:2;3909:9;3900:7;3896:23;3892:32;3889:52;;;3937:1;3934;3927:12;3889:52;3960:29;3979:9;3960:29;:::i;:::-;3950:39;;4008:38;4042:2;4031:9;4027:18;4008:38;:::i;:::-;3998:48;;3792:260;;;;;:::o;4731:118::-;4817:5;4810:13;4803:21;4796:5;4793:32;4783:60;;4839:1;4836;4829:12;4854:315;4919:6;4927;4980:2;4968:9;4959:7;4955:23;4951:32;4948:52;;;4996:1;4993;4986:12;4948:52;5019:29;5038:9;5019:29;:::i;:::-;5009:39;;5098:2;5087:9;5083:18;5070:32;5111:28;5133:5;5111:28;:::i;:::-;5158:5;5148:15;;;4854:315;;;;;:::o;5438:254::-;5506:6;5514;5567:2;5555:9;5546:7;5542:23;5538:32;5535:52;;;5583:1;5580;5573:12;5535:52;5606:29;5625:9;5606:29;:::i;:::-;5596:39;5682:2;5667:18;;;;5654:32;;-1:-1:-1;;;5438:254:1:o;6742:511::-;6810:6;6818;6826;6879:2;6867:9;6858:7;6854:23;6850:32;6847:52;;;6895:1;6892;6885:12;6847:52;6934:9;6921:23;6953:28;6975:5;6953:28;:::i;:::-;7000:5;-1:-1:-1;7057:2:1;7042:18;;7029:32;7070:30;7029:32;7070:30;:::i;:::-;7119:7;-1:-1:-1;7178:2:1;7163:18;;7150:32;7191:30;7150:32;7191:30;:::i;:::-;7240:7;7230:17;;;6742:511;;;;;:::o;7258:403::-;7344:6;7352;7360;7368;7421:3;7409:9;7400:7;7396:23;7392:33;7389:53;;;7438:1;7435;7428:12;7389:53;7461:29;7480:9;7461:29;:::i;:::-;7451:39;;7537:2;7526:9;7522:18;7509:32;7499:42;;7560:38;7594:2;7583:9;7579:18;7560:38;:::i;:::-;7550:48;;7617:38;7651:2;7640:9;7636:18;7617:38;:::i;:::-;7607:48;;7258:403;;;;;;;:::o;7666:254::-;7734:6;7742;7795:2;7783:9;7774:7;7770:23;7766:32;7763:52;;;7811:1;7808;7801:12;7763:52;7847:9;7834:23;7824:33;;7876:38;7910:2;7899:9;7895:18;7876:38;:::i;7925:241::-;7981:6;8034:2;8022:9;8013:7;8009:23;8005:32;8002:52;;;8050:1;8047;8040:12;8002:52;8089:9;8076:23;8108:28;8130:5;8108:28;:::i;8171:184::-;8223:77;8220:1;8213:88;8320:4;8317:1;8310:15;8344:4;8341:1;8334:15;8360:915;8442:6;8495:3;8483:9;8474:7;8470:23;8466:33;8463:53;;;8512:1;8509;8502:12;8463:53;8561:7;8554:4;8543:9;8539:20;8535:34;8525:62;;8583:1;8580;8573:12;8525:62;8616:2;8610:9;8658:3;8650:6;8646:16;8728:6;8716:10;8713:22;8692:18;8680:10;8677:34;8674:62;8671:242;;;8769:77;8766:1;8759:88;8870:4;8867:1;8860:15;8898:4;8895:1;8888:15;8671:242;8929:2;8922:22;8964:6;9008:3;8993:19;;9024;;;9021:39;;;9056:1;9053;9046:12;9021:39;9080:9;9098:146;9114:6;9109:3;9106:15;9098:146;;;9182:17;;9170:30;;9229:4;9220:14;;;;9131;9098:146;;;-1:-1:-1;9263:6:1;;8360:915;-1:-1:-1;;;;;8360:915:1:o;9280:184::-;9332:77;9329:1;9322:88;9429:4;9426:1;9419:15;9453:4;9450:1;9443:15;9469:184;9521:77;9518:1;9511:88;9618:4;9615:1;9608:15;9642:4;9639:1;9632:15;9658:128;9725:9;;;9746:11;;;9743:37;;;9760:18;;:::i;9791:168::-;9864:9;;;9895;;9912:15;;;9906:22;;9892:37;9882:71;;9933:18;;:::i;9964:274::-;10004:1;10030;10020:189;;10065:77;10062:1;10055:88;10166:4;10163:1;10156:15;10194:4;10191:1;10184:15;10020:189;-1:-1:-1;10223:9:1;;9964:274::o;10243:125::-;10308:9;;;10329:10;;;10326:36;;;10342:18;;:::i;10373:195::-;10412:3;10443:66;10436:5;10433:77;10430:103;;10513:18;;:::i;:::-;-1:-1:-1;10560:1:1;10549:13;;10373:195::o;11349:184::-;11419:6;11472:2;11460:9;11451:7;11447:23;11443:32;11440:52;;;11488:1;11485;11478:12;11440:52;-1:-1:-1;11511:16:1;;11349:184;-1:-1:-1;11349:184:1:o;20143:250::-;20228:1;20238:113;20252:6;20249:1;20246:13;20238:113;;;20328:11;;;20322:18;20309:11;;;20302:39;20274:2;20267:10;20238:113;;;-1:-1:-1;;20385:1:1;20367:16;;20360:27;20143:250::o;20398:287::-;20527:3;20565:6;20559:13;20581:66;20640:6;20635:3;20628:4;20620:6;20616:17;20581:66;:::i;:::-;20663:16;;;;;20398:287;-1:-1:-1;;20398:287:1:o;20690:245::-;20757:6;20810:2;20798:9;20789:7;20785:23;20781:32;20778:52;;;20826:1;20823;20816:12;20778:52;20858:9;20852:16;20877:28;20899:5;20877:28;:::i;23176:245::-;23255:6;23263;23316:2;23304:9;23295:7;23291:23;23287:32;23284:52;;;23332:1;23329;23322:12;23284:52;-1:-1:-1;;23355:16:1;;23411:2;23396:18;;;23390:25;23355:16;;23390:25;;-1:-1:-1;23176:245:1:o;23898:455::-;24047:2;24036:9;24029:21;24010:4;24079:6;24073:13;24122:6;24117:2;24106:9;24102:18;24095:34;24138:79;24210:6;24205:2;24194:9;24190:18;24185:2;24177:6;24173:15;24138:79;:::i;:::-;24269:2;24257:15;24274:66;24253:88;24238:104;;;;24344:2;24234:113;;23898:455;-1:-1:-1;;23898:455:1:o
Swarm Source
ipfs://838a9e12a21450aede84e9c7e1e559b8d8328c14801856b22b3efaf7e57470e7
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $1.55 | 7,309.2012 | $11,329.26 |
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.