Source Code
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 617 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Get Reward | 21588865 | 11 days ago | IN | 0 ETH | 0.00299768 | ||||
Withdraw Locked | 21210800 | 64 days ago | IN | 0 ETH | 0.00429297 | ||||
Sync | 21199950 | 65 days ago | IN | 0 ETH | 0.00109925 | ||||
Get Reward | 21199782 | 65 days ago | IN | 0 ETH | 0.00570967 | ||||
Sync | 20602171 | 149 days ago | IN | 0 ETH | 0.00009145 | ||||
Sync | 20602165 | 149 days ago | IN | 0 ETH | 0.00008907 | ||||
Sync | 20602163 | 149 days ago | IN | 0 ETH | 0.00008925 | ||||
Sync | 20602162 | 149 days ago | IN | 0 ETH | 0.00009043 | ||||
Sync | 20602116 | 149 days ago | IN | 0 ETH | 0.00009304 | ||||
Sync | 20602112 | 149 days ago | IN | 0 ETH | 0.00008612 | ||||
Sync | 20602108 | 149 days ago | IN | 0 ETH | 0.00018256 | ||||
Sync | 20530557 | 159 days ago | IN | 0 ETH | 0.0003311 | ||||
Sync | 19756371 | 267 days ago | IN | 0 ETH | 0.00102688 | ||||
Withdraw Locked | 19296019 | 331 days ago | IN | 0 ETH | 0.01472393 | ||||
Sync | 19073396 | 363 days ago | IN | 0 ETH | 0.00072437 | ||||
Sync | 18751983 | 408 days ago | IN | 0 ETH | 0.00864809 | ||||
Get Reward | 18525128 | 440 days ago | IN | 0 ETH | 0.00587213 | ||||
Withdraw Locked | 18389551 | 459 days ago | IN | 0 ETH | 0.00409852 | ||||
Get Reward | 18389549 | 459 days ago | IN | 0 ETH | 0.0039138 | ||||
Sync | 18114117 | 497 days ago | IN | 0 ETH | 0.00543162 | ||||
Get Reward | 17981830 | 516 days ago | IN | 0 ETH | 0.00333598 | ||||
Stake Locked | 17981829 | 516 days ago | IN | 0 ETH | 0.00861052 | ||||
Get Reward | 17981584 | 516 days ago | IN | 0 ETH | 0.00548829 | ||||
Stake Locked | 17981582 | 516 days ago | IN | 0 ETH | 0.01248229 | ||||
Sync | 17779692 | 544 days ago | IN | 0 ETH | 0.00732957 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
FraxUnifiedFarm_PosRebase_aFRAX
Compiler Version
v0.8.13+commit.abaa5c0e
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-04-22 */ // SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.8.0; // Sources flattened with hardhat v2.9.3 https://hardhat.org // 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/Curve/IveFXS.sol pragma abicoder v2; 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/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/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/Utils/Address.sol /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File contracts/ERC20/ERC20.sol /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20Mintable}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20 { using SafeMath for uint256; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; uint8 private _decimals; /** * @dev Sets the values for {name} and {symbol}, initializes {decimals} with * a default value of 18. * * To select a different value for {decimals}, use {_setupDecimals}. * * All three of these values are immutable: they can only be set once during * construction. */ constructor (string memory __name, string memory __symbol) public { _name = __name; _symbol = __symbol; _decimals = 18; } /** * @dev Returns the name of the token. */ function name() public view returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is * called. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view returns (uint8) { return _decimals; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address.approve(address spender, uint256 amount) */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}; * * Requirements: * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for `sender`'s tokens of at least * `amount`. */ function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { _transfer(sender, recipient, amount); _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } /** * @dev Moves tokens `amount` from `sender` to `recipient`. * * This is internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer(address sender, address recipient, uint256 amount) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements * * - `to` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); emit Transfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from the caller. * * See {ERC20-_burn}. */ function burn(uint256 amount) public virtual { _burn(_msgSender(), amount); } /** * @dev Destroys `amount` tokens from `account`, deducting from the caller's * allowance. * * See {ERC20-_burn} and {ERC20-allowance}. * * Requirements: * * - the caller must have allowance for `accounts`'s tokens of at least * `amount`. */ function burnFrom(address account, uint256 amount) public virtual { uint256 decreasedAllowance = allowance(account, _msgSender()).sub(amount, "ERC20: burn amount exceeds allowance"); _approve(account, _msgSender(), decreasedAllowance); _burn(account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); _totalSupply = _totalSupply.sub(amount); emit Transfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens. * * This is internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Destroys `amount` tokens from `account`.`amount` is then deducted * from the caller's allowance. * * See {_burn} and {_approve}. */ function _burnFrom(address account, uint256 amount) internal virtual { _burn(account, amount); _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, "ERC20: burn amount exceeds allowance")); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of `from`'s tokens * will be to transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of `from`'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:using-hooks.adoc[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } } // 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/ERC20/SafeERC20.sol /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // 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/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/Misc_AMOs/Lending_AMOs/aave/IAaveIncentivesControllerPartial.sol interface IAaveIncentivesControllerPartial { /** * @dev Returns the total of rewards of an user, already accrued + not yet accrued * @param user The address of the user * @return The rewards **/ function getRewardsBalance(address[] calldata assets, address user) external view returns (uint256); /** * @dev Claims reward for an user, on all the assets of the lending pool, accumulating the pending rewards * @param amount Amount of rewards to claim * @param to Address that will be receiving the rewards * @return Rewards claimed **/ function claimRewards( address[] calldata assets, uint256 amount, address to ) external returns (uint256); /** * @dev Claims reward for an user on behalf, on all the assets of the lending pool, accumulating the pending rewards. The caller must * be whitelisted via "allowClaimOnBehalf" function by the RewardsAdmin role manager * @param amount Amount of rewards to claim * @param user Address to check and claim rewards * @param to Address that will be receiving the rewards * @return Rewards claimed **/ function claimRewardsOnBehalf( address[] calldata assets, uint256 amount, address user, address to ) external returns (uint256); /** * @dev returns the unclaimed rewards of the user * @param user the address of the user * @return the unclaimed user rewards */ function getUserUnclaimedRewards(address user) external view returns (uint256); /** * @dev for backward compatibility with previous implementation of the Incentives controller */ function REWARD_TOKEN() external view returns (address); } // File contracts/Staking/FraxUnifiedFarmTemplate.sol pragma experimental ABIEncoderV2; // ==================================================================== // | ______ _______ | // | / _____________ __ __ / ____(_____ ____ _____ ________ | // | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ | // | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ | // | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ | // | | // ==================================================================== // ====================== FraxUnifiedFarmTemplate ===================== // ==================================================================== // Migratable 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 // Sam Sun: https://github.com/samczsun // 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 { using SafeERC20 for ERC20; /* ========== STATE VARIABLES ========== */ // Instances IveFXS private veFXS = IveFXS(0xc8418aF6358FFddA74e09Ca9CC3Fe03Ca6aDC5b0); // Frax related address internal constant frax_address = 0x853d955aCEf822Db058eb8505911ED77F175b99e; bool internal frax_is_token0; 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(3e18); // E18. 1x = e18 uint256 public lock_time_for_max_multiplier = 3 * 365 * 86400; // 3 years // uint256 public lock_time_for_max_multiplier = 2 * 86400; // 2 days uint256 public lock_time_min = 86400; // 1 * 86400 (1 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(2e18); // 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) internal 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 // List of valid migrators (set by governance) mapping(address => bool) internal valid_migrators; // Stakers set which migrator(s) they want to use mapping(address => mapping(address => bool)) internal staker_allowed_migrators; 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, migrations, and overrides bool public stakesUnlocked; // Release locked stakes in case of emergency bool internal migrationsOn; // Used for migrations. Prevents new stakes, but allows LP and reward withdrawals 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 isMigrating() { require(migrationsOn == true, "Not in migration"); _; } modifier updateRewardAndBalance(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 ) ) ; } // ------ 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 =============== */ // ------ MIGRATIONS ------ // Staker can allow a migrator function stakerToggleMigrator(address migrator_address) external { require(valid_migrators[migrator_address], "Invalid migrator address"); staker_allowed_migrators[msg.sender][migrator_address] = !staker_allowed_migrators[msg.sender][migrator_address]; } // Proxy can allow a staker to use their veFXS balance (the staker will have to reciprocally toggle them too) // Must come before stakerSetVeFXSProxy 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) 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"); 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) internal { // 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 updateRewardAndBalance(rewardee, true) returns (uint256[] memory rewards_before) { // 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]); } // Handle additional reward logic if (do_extra_logic) { _getRewardExtraLogic(rewardee, destination_address); } // Update the last reward claim time lastRewardClaimTime[rewardee] = block.timestamp; } // ------ 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)) <= ERC20(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 stkAAVE rewards get messed up for some reason, set this to 0 and it will skip if (rewardRatesManual[1] != 0) { // Aave aFRAX // ==================================== address[] memory the_assets = new address[](1); the_assets[0] = 0xd4937682df3C8aEF4FE912A96A74121C0829E664; // aFRAX uint256 stkaave_recd = IAaveIncentivesControllerPartial(0xd784927Ff2f95ba542BfC824c8a8a98F3495f6b5).claimRewards( the_assets, 115792089237316195423570985008687907853269984665640564039457584007913129639935, address(this) ); rewardRatesManual[1] = stkaave_recd / 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 / migrator 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; } function toggleMigrations() external onlyByOwnGov { migrationsOn = !migrationsOn; } // Adds supported migrator address function toggleMigrator(address migrator_address) external onlyByOwnGov { valid_migrators[migrator_address] = !valid_migrators[migrator_address]; } // 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; } /* ========== A CHICKEN ========== */ // // ,~. // ,-'__ `-, // {,-' `. } ,') // ,( a ) `-.__ ,',')~, // <=.) ( `-.__,==' ' ' '} // ( ) /) // `-'\ , ) // | \ `~. / // \ `._ \ / // \ `._____,' ,' // `-. ,' // `-._ _,-' // 77jj' // //_|| // __//--'/` // ,--'/` ' // // [hjw] https://textart.io/art/vw6Sa3iwqIRGkZsN1BC2vweF/chicken } // File contracts/Misc_AMOs/Lending_AMOs/aave/IScaledBalanceToken.sol interface IScaledBalanceToken { /** * @dev Returns the scaled balance of the user. The scaled balance is the sum of all the * updated stored balance divided by the reserve's liquidity index at the moment of the update * @param user The user whose balance is calculated * @return The scaled balance of the user **/ function scaledBalanceOf(address user) external view returns (uint256); /** * @dev Returns the scaled balance of the user and the scaled total supply. * @param user The address of the user * @return The scaled balance of the user * @return The scaled balance and the scaled total supply **/ function getScaledUserBalanceAndSupply(address user) external view returns (uint256, uint256); /** * @dev Returns the scaled total supply of the variable debt token. Represents sum(debt/index) * @return The scaled total supply **/ function scaledTotalSupply() external view returns (uint256); } // File contracts/Misc_AMOs/Lending_AMOs/aave/IAToken.sol interface IAToken is IERC20, IScaledBalanceToken { function ATOKEN_REVISION() external view returns (uint256); function DOMAIN_SEPARATOR() external view returns (bytes32); function EIP712_REVISION() external view returns (bytes memory); function PERMIT_TYPEHASH() external view returns (bytes32); function POOL() external view returns (address); function RESERVE_TREASURY_ADDRESS() external view returns (address); function UINT_MAX_VALUE() external view returns (uint256); function UNDERLYING_ASSET_ADDRESS() external view returns (address); /** * @dev Emitted after the mint action * @param from The address performing the mint * @param value The amount being * @param index The new liquidity index of the reserve **/ event Mint(address indexed from, uint256 value, uint256 index); /** * @dev Mints `amount` aTokens to `user` * @param user The address receiving the minted tokens * @param amount The amount of tokens getting minted * @param index The new liquidity index of the reserve * @return `true` if the the previous balance of the user was 0 */ function mint( address user, uint256 amount, uint256 index ) external returns (bool); /** * @dev Emitted after aTokens are burned * @param from The owner of the aTokens, getting them burned * @param target The address that will receive the underlying * @param value The amount being burned * @param index The new liquidity index of the reserve **/ event Burn(address indexed from, address indexed target, uint256 value, uint256 index); /** * @dev Emitted during the transfer action * @param from The user whose tokens are being transferred * @param to The recipient * @param value The amount being transferred * @param index The new liquidity index of the reserve **/ event BalanceTransfer(address indexed from, address indexed to, uint256 value, uint256 index); /** * @dev Burns aTokens from `user` and sends the equivalent amount of underlying to `receiverOfUnderlying` * @param user The owner of the aTokens, getting them burned * @param receiverOfUnderlying The address that will receive the underlying * @param amount The amount being burned * @param index The new liquidity index of the reserve **/ function burn( address user, address receiverOfUnderlying, uint256 amount, uint256 index ) external; /** * @dev Mints aTokens to the reserve treasury * @param amount The amount of tokens getting minted * @param index The new liquidity index of the reserve */ function mintToTreasury(uint256 amount, uint256 index) external; /** * @dev Transfers aTokens in the event of a borrow being liquidated, in case the liquidators reclaims the aToken * @param from The address getting liquidated, current owner of the aTokens * @param to The recipient * @param value The amount of tokens getting transferred **/ function transferOnLiquidation( address from, address to, uint256 value ) external; /** * @dev Transfers the underlying asset to `target`. Used by the LendingPool to transfer * assets in borrow(), withdraw() and flashLoan() * @param user The recipient of the aTokens * @param amount The amount getting transferred * @return The amount transferred **/ function transferUnderlyingTo(address user, uint256 amount) external returns (uint256); } // File contracts/Misc_AMOs/Lending_AMOs/aave/ILendingPool.sol interface ILendingPool { function FLASHLOAN_PREMIUM_TOTAL ( ) external view returns ( uint256 ); function LENDINGPOOL_REVISION ( ) external view returns ( uint256 ); function MAX_NUMBER_RESERVES ( ) external view returns ( uint256 ); function MAX_STABLE_RATE_BORROW_SIZE_PERCENT ( ) external view returns ( uint256 ); function borrow ( address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf ) external; function deposit ( address asset, uint256 amount, address onBehalfOf, uint16 referralCode ) external; function finalizeTransfer ( address asset, address from, address to, uint256 amount, uint256 balanceFromBefore, uint256 balanceToBefore ) external; function flashLoan ( address receiverAddress, address[] memory assets, uint256[] memory amounts, uint256[] memory modes, address onBehalfOf, bytes memory params, uint16 referralCode ) external; function getAddressesProvider ( ) external view returns ( address ); // function getConfiguration ( address asset ) external view returns ( tuple ); // function getReserveData ( address asset ) external view returns ( tuple ); function getReserveNormalizedIncome ( address asset ) external view returns ( uint256 ); function getReserveNormalizedVariableDebt ( address asset ) external view returns ( uint256 ); function getReservesList ( ) external view returns ( address[] memory ); function getUserAccountData ( address user ) external view returns ( uint256 totalCollateralETH, uint256 totalDebtETH, uint256 availableBorrowsETH, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor ); // function getUserConfiguration ( address user ) external view returns ( tuple ); function initReserve ( address asset, address aTokenAddress, address stableDebtAddress, address variableDebtAddress, address interestRateStrategyAddress ) external; function initialize ( address provider ) external; function liquidationCall ( address collateralAsset, address debtAsset, address user, uint256 debtToCover, bool receiveAToken ) external; function paused ( ) external view returns ( bool ); function rebalanceStableBorrowRate ( address asset, address user ) external; function repay ( address asset, uint256 amount, uint256 rateMode, address onBehalfOf ) external returns ( uint256 ); function setConfiguration ( address asset, uint256 configuration ) external; function setPause ( bool val ) external; function setReserveInterestRateStrategyAddress ( address asset, address rateStrategyAddress ) external; function setUserUseReserveAsCollateral ( address asset, bool useAsCollateral ) external; function swapBorrowRateMode ( address asset, uint256 rateMode ) external; function withdraw ( address asset, uint256 amount, address to ) external returns ( uint256 ); } // File contracts/Staking/FraxUnifiedFarm_PosRebase.sol // ==================================================================== // | ______ _______ | // | / _____________ __ __ / ____(_____ ____ _____ ________ | // | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ | // | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ | // | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ | // | | // ==================================================================== // ===================== FraxUnifiedFarm_PosRebase ==================== // ==================================================================== // For positive rebase ERC20 Tokens like Aave's aToken and Compound's cToken // Uses FraxUnifiedFarmTemplate.sol // -------------------- VARIES -------------------- // Aave V2 // ------------------------------------------------ contract FraxUnifiedFarm_PosRebase is FraxUnifiedFarmTemplate { /* ========== STATE VARIABLES ========== */ // -------------------- VARIES -------------------- // Aave V2 IAToken public stakingToken; // Need to store this when the user stakes. If they lockAdditional, the base value needs to accrue and the // Stored liquidity index needs to be updated // https://docs.aave.com/developers/v/2.0/the-core-protocol/atokens#scaledbalanceof mapping(bytes32 => uint256) public storedStkLiqIdx; // kek_id -> liquidity index. // ------------------------------------------------ // 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 -------------------- // Aave V2 stakingToken = IAToken(_stakingToken); } /* ============= VIEWS ============= */ // ------ FRAX RELATED ------ function fraxPerLPToken() public view override returns (uint256) { // Get the amount of FRAX 'inside' of the lp tokens uint256 frax_per_lp_token; // Aave V2 // ============================================ { // Always 1-to-1, for simplicity. Autocompounding is handled by _accrueInterest // Users can accrue up their principal by calling lockAdditional with 0 amount. // Also will accrue at withdrawal time frax_per_lp_token = 1e18; } return frax_per_lp_token; } // ------ LIQUIDITY AND WEIGHTS ------ // 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) { // This is only called for the first stake to make sure the veFXS multiplier is not cut in half midpoint_vefxs_multiplier = new_vefxs_multiplier; } else { 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]; uint256 lock_multiplier = thisStake.lock_multiplier; // 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 - lastRewardClaimTime[account]; uint256 time_after_expiry = block.timestamp - thisStake.ending_timestamp; // Get the weighted-average lock_multiplier uint256 numerator = (lock_multiplier * time_before_expiry) + (MULTIPLIER_PRECISION * time_after_expiry); lock_multiplier = numerator / (time_before_expiry + time_after_expiry); } // Otherwise, it needs to just be 1x else { lock_multiplier = MULTIPLIER_PRECISION; } } uint256 liquidity = thisStake.liquidity; uint256 combined_boosted_amount = (liquidity * (lock_multiplier + midpoint_vefxs_multiplier)) / MULTIPLIER_PRECISION; new_combined_weight = new_combined_weight + combined_boosted_amount; } } // ------ REBASE RELATED ------ // Aave V2 // ============================================ // Get currentLiquidityIndex from AAVE function currLiqIdx() public view returns (uint256) { return ILendingPool(stakingToken.POOL()).getReserveNormalizedIncome(frax_address); } // ------ 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 _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 // REBASE: If you simply want to accrue interest, call this with addl_liq = 0 function lockAdditional(bytes32 kek_id, uint256 addl_liq) updateRewardAndBalance(msg.sender, true) public { // Get the stake and its index (LockedStake memory thisStake, uint256 theArrayIndex) = _getStake(msg.sender, kek_id); // Accrue the interest and get the updated stake (thisStake, ) = _accrueInterest(msg.sender, thisStake, theArrayIndex); // Return early if only accruing, to save gas if (addl_liq == 0) return; // 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 _total_liquidity_locked += addl_liq; _locked_liquidity[msg.sender] += addl_liq; { address the_proxy = getProxyFor(msg.sender); if (the_proxy != address(0)) proxy_lp_balances[the_proxy] += addl_liq; } // Need to call to update the combined weights _updateRewardAndBalance(msg.sender, false); } // Two different stake functions are needed because of delegateCall and msg.sender issues (important for migration) 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 updateRewardAndBalance(staker_address, true) returns (bytes32) { require(stakingPaused == false || valid_migrators[msg.sender] == true, "Staking paused or in migration"); 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 )); // Store the liquidity index. Used later to give back principal + accrued interest storedStkLiqIdx[kek_id] = currLiqIdx(); // Update liquidities _total_liquidity_locked += liquidity; _locked_liquidity[staker_address] += liquidity; { address the_proxy = getProxyFor(staker_address); if (the_proxy != address(0)) proxy_lp_balances[the_proxy] += liquidity; } // Need to call again to make sure everything is correct _updateRewardAndBalance(staker_address, false); 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 migration) 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 // functions like migrator_withdraw_locked() and withdrawLocked() 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); // Accrue the interest and get the updated stake (thisStake, ) = _accrueInterest(staker_address, thisStake, theArrayIndex); // Do safety checks require(block.timestamp >= thisStake.ending_timestamp || stakesUnlocked == true || valid_migrators[msg.sender] == true, "Stake is still locked!"); uint256 liquidity = thisStake.liquidity; if (liquidity > 0) { // Update liquidities _total_liquidity_locked -= liquidity; _locked_liquidity[staker_address] -= liquidity; { address the_proxy = getProxyFor(staker_address); if (the_proxy != address(0)) proxy_lp_balances[the_proxy] -= liquidity; } // Remove the stake from the array delete lockedStakes[staker_address][theArrayIndex]; // Give the tokens to the destination_address // Should throw if insufficient balance stakingToken.transfer(destination_address, liquidity); // Need to call again to make sure everything is correct _updateRewardAndBalance(staker_address, false); // REBASE: leave liquidity in the event tracking alone, not giveBackAmt emit WithdrawLocked(staker_address, liquidity, kek_id, destination_address); } return liquidity; } // REBASE SPECIFIC // Catches-up the user's accrued interest and sets it as the new principal (liquidity) function _accrueInterest( address staker_address, LockedStake memory thisStake, uint256 theArrayIndex ) internal returns (LockedStake memory, uint256) { // Calculate the new liquidity as well as the diff // new pricipal = (old principal ∗ currentLiquidityIndex) / (old liquidity index) uint256 new_liq = (thisStake.liquidity * currLiqIdx()) / storedStkLiqIdx[thisStake.kek_id]; uint256 liq_diff = new_liq - thisStake.liquidity; // Update the new principal lockedStakes[staker_address][theArrayIndex].liquidity = new_liq; // Update the liquidity totals _total_liquidity_locked += liq_diff; _locked_liquidity[staker_address] += liq_diff; { address the_proxy = getProxyFor(staker_address); if (the_proxy != address(0)) proxy_lp_balances[the_proxy] += liq_diff; } // Store the new liquidity index. Used later to give back principal + accrued interest storedStkLiqIdx[thisStake.kek_id] = currLiqIdx(); return (lockedStakes[staker_address][theArrayIndex], theArrayIndex); } function _getRewardExtraLogic(address rewardee, address destination_address) internal override { // Do nothing } /* ========== RESTRICTED FUNCTIONS - Curator / migrator callable ========== */ // Migrator can stake for someone else (they won't be able to withdraw it back though, only staker_address can). function migrator_stakeLocked_for(address staker_address, uint256 amount, uint256 secs, uint256 start_timestamp) external isMigrating { require(staker_allowed_migrators[staker_address][msg.sender] && valid_migrators[msg.sender], "Mig. invalid or unapproved"); _stakeLocked(staker_address, msg.sender, amount, secs, start_timestamp); } // Used for migrations function migrator_withdraw_locked(address staker_address, bytes32 kek_id) external isMigrating { require(staker_allowed_migrators[staker_address][msg.sender] && valid_migrators[msg.sender], "Mig. invalid or unapproved"); _withdrawLocked(staker_address, msg.sender, kek_id); } /* ========== RESTRICTED FUNCTIONS - Owner or timelock only ========== */ // Inherited... /* ========== EVENTS ========== */ 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_PosRebase_aFRAX.sol contract FraxUnifiedFarm_PosRebase_aFRAX is FraxUnifiedFarm_PosRebase { constructor ( address _owner, address[] memory _rewardTokens, address[] memory _rewardManagers, uint256[] memory _rewardRates, address[] memory _gaugeControllers, address[] memory _rewardDistributors, address _stakingToken ) FraxUnifiedFarm_PosRebase(_owner , _rewardTokens, _rewardManagers, _rewardRates, _gaugeControllers, _rewardDistributors, _stakingToken) {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"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":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":"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":"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":"currLiqIdx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":[],"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":"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_PosRebase.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":"staker_address","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"secs","type":"uint256"},{"internalType":"uint256","name":"start_timestamp","type":"uint256"}],"name":"migrator_stakeLocked_for","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"staker_address","type":"address"},{"internalType":"bytes32","name":"kek_id","type":"bytes32"}],"name":"migrator_withdraw_locked","outputs":[],"stateMutability":"nonpayable","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":"migrator_address","type":"address"}],"name":"stakerToggleMigrator","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 IAToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"storedStkLiqIdx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":[],"name":"toggleMigrations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"migrator_address","type":"address"}],"name":"toggleMigrator","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"}],"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
6080604052600380546001600160a01b03191673c8418af6358ffdda74e09ca9cc3fe03ca6adc5b01790556729a2241af62c00006007556305a39a8060085562015180600955673782dace9d900000600a55671bc16d674ec80000600b819055600c553480156200006f57600080fd5b5060405162005abc38038062005abc8339810160408190526200009291620005ae565b86868686868686868686868686856001600160a01b038116620000fb5760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f74206265203000000000000000604482015260640160405180910390fd5b600080546001600160a01b0319166001600160a01b03831690811782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a150600160025584516200016d90601190602088019062000385565b5081516200018390601290602085019062000385565b5080516200019990601390602084019062000385565b508251620001af906014906020860190620003ef565b5060005b85518110156200031a578060156000888481518110620001d757620001d7620006b5565b6020908102919091018101516001600160a01b03168252810191909152604001600090812091909155601680546001810182559082527fd833147d7dc355ba459fc788f669e58cfaf9dc25ddcd0702e87d69c7b512428901558451859082908110620002475762000247620006b5565b602002602001015160106000888481518110620002685762000268620006b5565b6020908102919091018101516001600160a01b03908116835290820192909252604001600090812080546001600160a01b03191693909216929092179055601a805460018181019092557f057c384a7d1c54f3a1b2e5e67b2617b8224fdfd1ea7234eea573a6ff665ff63e01829055601b8054918201815582527f3ad8aa4f87544323a9d1e5dd902f40c356527a7955687113db5f9a85ad579dc10155806200031181620006e1565b915050620001b3565b506024805460ff191690554260068190556200033b9062093a8090620006fd565b6005555050602480546001600160a01b039096166501000000000002600160281b600160c81b03199096169590951790945550620007189f50505050505050505050505050505050565b828054828255906000526020600020908101928215620003dd579160200282015b82811115620003dd57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620003a6565b50620003eb9291506200042d565b5090565b828054828255906000526020600020908101928215620003dd579160200282015b82811115620003dd57825182559160200191906001019062000410565b5b80821115620003eb57600081556001016200042e565b80516001600160a01b03811681146200045c57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620004a257620004a262000461565b604052919050565b60006001600160401b03821115620004c657620004c662000461565b5060051b60200190565b600082601f830112620004e257600080fd5b81516020620004fb620004f583620004aa565b62000477565b82815260059290921b840181019181810190868411156200051b57600080fd5b8286015b848110156200054157620005338162000444565b83529183019183016200051f565b509695505050505050565b600082601f8301126200055e57600080fd5b8151602062000571620004f583620004aa565b82815260059290921b840181019181810190868411156200059157600080fd5b8286015b8481101562000541578051835291830191830162000595565b600080600080600080600060e0888a031215620005ca57600080fd5b620005d58862000444565b60208901519097506001600160401b0380821115620005f357600080fd5b620006018b838c01620004d0565b975060408a01519150808211156200061857600080fd5b620006268b838c01620004d0565b965060608a01519150808211156200063d57600080fd5b6200064b8b838c016200054c565b955060808a01519150808211156200066257600080fd5b620006708b838c01620004d0565b945060a08a01519150808211156200068757600080fd5b50620006968a828b01620004d0565b925050620006a760c0890162000444565b905092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201620006f657620006f6620006cb565b5060010190565b60008219821115620007135762000713620006cb565b500190565b61539480620007286000396000f3fe608060405234801561001057600080fd5b50600436106104205760003560e01c80638da5cb5b11610235578063d42fc9b411610135578063e7f30582116100c8578063f2a8d34911610097578063f77e34d11161007c578063f77e34d1146109d1578063facefb64146109e4578063fff6cae9146109f757600080fd5b8063f2a8d349146109b5578063f2caeb1e146109be57600080fd5b8063e7f305821461097d578063eb3c209e14610990578063ebe2b12b146109a3578063f288baf6146109ac57600080fd5b8063de1a655111610104578063de1a655114610947578063e01f62bf1461095a578063e1ba95d214610962578063e44b9fa51461096a57600080fd5b8063d42fc9b4146108d8578063d5e1a9c6146108eb578063d7400d56146108fe578063d9f96e8d1461091157600080fd5b8063b94c4dcb116101c8578063c8f33c9111610197578063cc2abd641161017c578063cc2abd64146108b3578063cdc82e80146108c6578063d2010fb4146108cf57600080fd5b8063c8f33c9114610874578063ca6df29d1461087d57600080fd5b8063b94c4dcb14610825578063b9ec92231461082e578063c00007b01461084e578063c35438261461086157600080fd5b8063a2217bc511610204578063a2217bc5146107ee578063aa1d4fce146107f6578063affaa7a4146107ff578063b85efd061461081257600080fd5b80638da5cb5b1461079b57806391cf600a146107bb5780639637927f146107ce578063a0f23476146107db57600080fd5b8063387edc861161034057806370641a36116102d357806379ba5097116102a25780637f472e54116102875780637f472e54146107475780638980f11f1461075a5780638bad86a71461076d57600080fd5b806379ba5097146107205780637d6ef08e1461072857600080fd5b806370641a36146106a157806372f702f3146106a95780637910d17b146106d25780637970833e146106e557600080fd5b80635bfd92581161030f5780635bfd92581461066257806364f2c0601461067057806369339245146106785780636e27cef91461069857600080fd5b8063387edc86146105e657806341a16f3f146105f95780634fd2b5361461062f57806353a47bb71461064257600080fd5b8063215951e2116103b85780632c0c2a0a116103875780632c0c2a0a146105805780633650aff21461059357806336f89af2146105a6578063386a9525146105dc57600080fd5b8063215951e2146104e7578063231b68dc146104ef57806328408bab1461051257806328ef934e1461056d57600080fd5b806317b18c89116103f457806317b18c89146104995780631c1f78eb146104ac5780631e090f01146104b45780631face856146104d457600080fd5b80628cc262146104255780630d7bac4f1461044e57806312edb24c1461046f5780631627540c14610484575b600080fd5b610438610433366004614cd4565b6109ff565b6040516104459190614cf1565b60405180910390f35b61046161045c366004614d35565b610b7e565b604051908152602001610445565b610477610bce565b6040516104459190614d9f565b610497610492366004614cd4565b610c3d565b005b6104616104a7366004614db2565b610d62565b610438610dec565b6104c76104c2366004614cd4565b610e8d565b6040516104459190614dd4565b6104616104e2366004614cd4565b610f41565b610461610f86565b6105026104fd366004614e42565b6110c2565b6040519015158152602001610445565b610548610520366004614cd4565b60236020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610445565b61049761057b366004614e7b565b611130565b61046161058e366004614cd4565b611270565b6104976105a1366004614cd4565b61154e565b6104616105b4366004614cd4565b73ffffffffffffffffffffffffffffffffffffffff166000908152601f602052604090205490565b61046162093a8081565b6104976105f4366004614cd4565b611641565b610548610607366004614cd4565b60106020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b61046161063d366004614cd4565b61172c565b6001546105489073ffffffffffffffffffffffffffffffffffffffff1681565b670de0b6b3a7640000610461565b601d54610461565b610461610686366004614cd4565b60156020526000908152604090205481565b61046160095481565b61043861174d565b6024546105489065010000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b6104386106e0366004614ec4565b6118ac565b6106f86106f3366004614ef2565b611928565b604080519586526020860194909452928401919091526060830152608082015260a001610445565b610497611976565b610461610736366004614cd4565b602080526000908152604090205481565b610461610755366004614cd4565b611ac1565b610497610768366004614ef2565b611ad8565b61078061077b366004614cd4565b611cc1565b60408051938452602084019290925290820152606001610445565b6000546105489073ffffffffffffffffffffffffffffffffffffffff1681565b6104976107c9366004614cd4565b611f8f565b6024546105029060ff1681565b6104616107e9366004614cd4565b612082565b61049761213d565b610461600a5481565b61049761080d366004614cd4565b612216565b610497610820366004614db2565b612306565b61046160085481565b61046161083c366004614d35565b60256020526000908152604090205481565b61043861085c366004614cd4565b6124cd565b61054861086f366004614cd4565b612555565b61046160065481565b61046161088b366004614cd4565b73ffffffffffffffffffffffffffffffffffffffff1660009081526026602052604090205490565b6104976108c1366004614f1e565b6125b3565b61046160075481565b61046160045481565b6104616108e6366004614cd4565b6126ec565b6104976108f9366004614f69565b612728565b61049761090c366004614cd4565b612917565b61046161091f366004614cd4565b73ffffffffffffffffffffffffffffffffffffffff166000908152601e602052604090205490565b610497610955366004614e42565b612abc565b601c54610461565b610497612ba3565b610461610978366004614fbc565b612c74565b61049761098b366004614cd4565b612d63565b61049761099e366004614ef2565b612ebd565b61046160055481565b610461600b5481565b610461600c5481565b6104616109cc366004614d35565b612ff4565b6104976109df366004614fe1565b61310b565b6104976109f236600461502d565b6132e1565b6104976134a1565b60606000610a0b61174d565b60115490915067ffffffffffffffff811115610a2957610a29614ffe565b604051908082528060200260200182016040528015610a52578160200160208202803683370190505b5073ffffffffffffffffffffffffffffffffffffffff84166000908152601f602052604090205490925015610b785760005b601154811015610b765773ffffffffffffffffffffffffffffffffffffffff84166000818152601860209081526040808320858452825280832054938352601782528083208584529091529020548351670de0b6b3a76400009190859085908110610af157610af16150d2565b6020026020010151610b039190615130565b73ffffffffffffffffffffffffffffffffffffffff87166000908152601f6020526040902054610b339190615147565b610b3d9190615184565b610b4791906151bf565b838281518110610b5957610b596150d2565b602090810291909101015280610b6e816151d7565b915050610a84565b505b50919050565b600754600854600091610bc891610b9d670de0b6b3a764000083615130565b610ba79086615147565b610bb19190615184565b610bc390670de0b6b3a76400006151bf565b6134d2565b92915050565b60606011805480602002602001604051908101604052809291908181526020018280548015610c3357602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610c08575b5050505050905090565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ce9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201527f6f726d207468697320616374696f6e000000000000000000000000000000000060648201526084015b60405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229060200160405180910390a150565b60006002805403610dcf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610ce0565b60028055610de033808585426134ea565b60016002559392505050565b60145460609067ffffffffffffffff811115610e0a57610e0a614ffe565b604051908082528060200260200182016040528015610e33578160200160208202803683370190505b50905060005b601454811015610e895762093a80610e5082612ff4565b610e5a9190615147565b828281518110610e6c57610e6c6150d2565b602090810291909101015280610e81816151d7565b915050610e39565b5090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152602660209081526040808320805482518185028101850190935280835260609492939192909184015b82821015610f3657838290600052602060002090600502016040518060a00160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152505081526020019060010190610ed2565b505050509050919050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152602080526040812054600454670de0b6b3a764000091610f7c91615147565b610bc89190615184565b6000602460059054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637535d2466040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ff5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611019919061520f565b6040517fd15e005300000000000000000000000000000000000000000000000000000000815273853d955acef822db058eb8505911ed77f175b99e600482015273ffffffffffffffffffffffffffffffffffffffff919091169063d15e005390602401602060405180830381865afa158015611099573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110bd919061522c565b905090565b6000805473ffffffffffffffffffffffffffffffffffffffff908116908416036110ee57506001610bc8565b73ffffffffffffffffffffffffffffffffffffffff82811660009081526010602052604090205481851691160361112757506001610bc8565b50600092915050565b60245460ff6101009091041615156001146111a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4e6f7420696e206d6967726174696f6e000000000000000000000000000000006044820152606401610ce0565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260226020908152604080832033845290915290205460ff1680156111f657503360009081526021602052604090205460ff165b61125c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d69672e20696e76616c6964206f7220756e617070726f7665640000000000006044820152606401610ce0565b61126984338585856134ea565b5050505050565b6000808061127d84612555565b905073ffffffffffffffffffffffffffffffffffffffff811615611334576003546040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152909116906370a0823190602401602060405180830381865afa15801561130b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061132f919061522c565b6113c8565b6003546040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152909116906370a0823190602401602060405180830381865afa1580156113a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c8919061522c565b91506000670de0b6b3a7640000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611442573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611466919061522c565b6114709190615147565b600a54600b546114809086615147565b61148a9190615147565b6114949190615184565b905060008073ffffffffffffffffffffffffffffffffffffffff8416156114c3576114be84611ac1565b6114cc565b6114cc8761172c565b9050801561151e576000816114e9670de0b6b3a764000088615147565b6114f39190615184565b9050670de0b6b3a7640000600b548261150c9190615147565b6115169190615184565b925050611523565b600091505b508082116115315780611533565b815b9450600b5485111561154557600b5494505b50505050919050565b60005473ffffffffffffffffffffffffffffffffffffffff163314806115875750738412ebf45bac1b340bbe8f318b928c466c4e39ca33145b6115ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4e6f74206f776e6572206f722074696d656c6f636b00000000000000000000006044820152606401610ce0565b73ffffffffffffffffffffffffffffffffffffffff16600090815260216020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b60028054036116ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610ce0565b600280556024546301000000900460ff1615611724576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f5265776172647320636f6c6c656374696f6e20706175736564000000000000006044820152606401610ce0565b506001600255565b6000670de0b6b3a7640000600c54611743846126ec565b610f7c9190615147565b6060601c54600014806117605750601d54155b156117ba576016805480602002602001604051908101604052809291908181526020018280548015610c3357602002820191906000526020600020905b81548152602001906001019080831161179d575050505050905090565b60115467ffffffffffffffff8111156117d5576117d5614ffe565b6040519080825280602002602001820160405280156117fe578160200160208202803683370190505b50905060005b601654811015610e8957601d5461181a82612ff4565b60065461182561392a565b61182f9190615130565b6118399190615147565b61184b90670de0b6b3a7640000615147565b6118559190615184565b60168281548110611868576118686150d2565b906000526020600020015461187d91906151bf565b82828151811061188f5761188f6150d2565b6020908102919091010152806118a4816151d7565b915050611804565b60606002805403611919576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610ce0565b60028055610de0338484613938565b6026602052816000526040600020818154811061194457600080fd5b600091825260209091206005909102018054600182015460028301546003840154600490940154929550909350919085565b60015473ffffffffffffffffffffffffffffffffffffffff163314611a1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527f2063616e20616363657074206f776e65727368697000000000000000000000006064820152608401610ce0565b6000546001546040805173ffffffffffffffffffffffffffffffffffffffff93841681529290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a160018054600080547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff841617909155169055565b6000670de0b6b3a7640000600c5461174384610f41565b600054829073ffffffffffffffffffffffffffffffffffffffff16331480611b055750611b0533826110c2565b611b6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f74206f776e6572206f7220746b6e206d67720000000000000000000000006044820152606401610ce0565b6000805b601154811015611be5578473ffffffffffffffffffffffffffffffffffffffff1660118281548110611ba357611ba36150d2565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1603611bd35760019150611be5565b80611bdd816151d7565b915050611b6f565b50808015611c19575073ffffffffffffffffffffffffffffffffffffffff8481166000908152601060205260409020541633145b80611c44575080158015611c44575060005473ffffffffffffffffffffffffffffffffffffffff1633145b15611c5a57611c54843385613b5c565b50505050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4e6f2076616c696420746f6b656e7320746f207265636f7665720000000000006044820152606401610ce0565b505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152601f60205260408120549080611cf284611270565b73ffffffffffffffffffffffffffffffffffffffff85166000908152601e602052604081205491935090158015611d4c575073ffffffffffffffffffffffffffffffffffffffff85166000908152601f6020526040902054155b15611d58575081611d98565b73ffffffffffffffffffffffffffffffffffffffff85166000908152600d6020526040902054600290611d8b90856151bf565b611d959190615184565b90505b6000915060005b73ffffffffffffffffffffffffffffffffffffffff8616600090815260266020526040902054811015611f865773ffffffffffffffffffffffffffffffffffffffff86166000908152602660205260408120805483908110611e0357611e036150d2565b90600052602060002090600502016040518060a001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481525050905060008160800151905042826060015111611f3357606082015173ffffffffffffffffffffffffffffffffffffffff89166000908152601960205260409020541015611f285773ffffffffffffffffffffffffffffffffffffffff88166000908152601960205260408120546060840151611eca9190615130565b90506000836060015142611ede9190615130565b90506000611ef482670de0b6b3a7640000615147565b611efe8486615147565b611f0891906151bf565b9050611f1482846151bf565b611f1e9082615184565b9350505050611f33565b50670de0b6b3a76400005b60408201516000670de0b6b3a7640000611f4d87856151bf565b611f579084615147565b611f619190615184565b9050611f6d81886151bf565b9650505050508080611f7e906151d7565b915050611d9f565b50509193909250565b60005473ffffffffffffffffffffffffffffffffffffffff16331480611fc85750738412ebf45bac1b340bbe8f318b928c466c4e39ca33145b61202e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4e6f74206f776e6572206f722074696d656c6f636b00000000000000000000006044820152606401610ce0565b73ffffffffffffffffffffffffffffffffffffffff166000908152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b6000600454600c546120949190615147565b6003546040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152670de0b6b3a76400009283929116906370a0823190602401602060405180830381865afa15801561210f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612133919061522c565b6117439190615147565b60005473ffffffffffffffffffffffffffffffffffffffff163314806121765750738412ebf45bac1b340bbe8f318b928c466c4e39ca33145b6121dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4e6f74206f776e6572206f722074696d656c6f636b00000000000000000000006044820152606401610ce0565b602480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff81166101009182900460ff1615909102179055565b73ffffffffffffffffffffffffffffffffffffffff811660009081526021602052604090205460ff166122a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f496e76616c6964206d69677261746f72206164647265737300000000000000006044820152606401610ce0565b33600090815260226020908152604080832073ffffffffffffffffffffffffffffffffffffffff94909416835292905220805460ff8116157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909116179055565b3360016123138282613cc5565b6000806123203387613de7565b9150915061232f338383613fac565b5091506000859003612342575050611c54565b600085836040015161235491906151bf565b90506024546123849065010000000000900473ffffffffffffffffffffffffffffffffffffffff163330896141dc565b6040805160a0810182528881526020858101518183015281830184905260608087015190830152608080870151908301523360009081526026909152919091208054849081106123d6576123d66150d2565b9060005260206000209060050201600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015590505085601c600082825461242b91906151bf565b9091555050336000908152601e60205260408120805488929061244f9084906151bf565b909155506000905061246033612555565b905073ffffffffffffffffffffffffffffffffffffffff8116156124b85773ffffffffffffffffffffffffffffffffffffffff81166000908152602080526040812080548992906124b29084906151bf565b90915550505b506124c4336000613cc5565b50505050505050565b6060600280540361253a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610ce0565b6002805561254a33836001613938565b600160025592915050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600e602052604081205460ff1615612587575090565b5073ffffffffffffffffffffffffffffffffffffffff9081166000908152602360205260409020541690565b60005473ffffffffffffffffffffffffffffffffffffffff163314806125ec5750738412ebf45bac1b340bbe8f318b928c466c4e39ca33145b612652576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4e6f74206f776e6572206f722074696d656c6f636b00000000000000000000006044820152606401610ce0565b602480549115156301000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffff93151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff95151564010000000002959095167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff00ffff909316929092179390931791909116179055565b73ffffffffffffffffffffffffffffffffffffffff81166000908152601e6020526040812054600454670de0b6b3a764000091610f7c91615147565b600054849073ffffffffffffffffffffffffffffffffffffffff16331480612755575061275533826110c2565b6127bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f74206f776e6572206f7220746b6e206d67720000000000000000000000006044820152606401610ce0565b73ffffffffffffffffffffffffffffffffffffffff85166000908152601560205260409020546014805486929081106127f6576127f66150d2565b9060005260206000200181905550826012601560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205481548110612857576128576150d2565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9485161790559187168152601590915260409020546013805484929081106128c8576128c86150d2565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600e602052604090205460ff166129a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c69642070726f7879000000000000000000000000000000000000006044820152606401610ce0565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600f6020908152604080832033845290915290205460ff16612a40576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f50726f787920686173206e6f7420616c6c6f77656420796f75207965740000006044820152606401610ce0565b33600090815260236020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616908117909155601e8352818420549084529180528220805491929091612ab49084906151bf565b909155505050565b600054829073ffffffffffffffffffffffffffffffffffffffff16331480612ae95750612ae933826110c2565b612b4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f74206f776e6572206f7220746b6e206d67720000000000000000000000006044820152606401610ce0565b5073ffffffffffffffffffffffffffffffffffffffff918216600090815260106020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001691909216179055565b60005473ffffffffffffffffffffffffffffffffffffffff16331480612bdc5750738412ebf45bac1b340bbe8f318b928c466c4e39ca33145b612c42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4e6f74206f776e6572206f722074696d656c6f636b00000000000000000000006044820152606401610ce0565b602480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b60006002805403612ce1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610ce0565b6002805560245462010000900460ff1615612d58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f5769746864726177616c732070617573656400000000000000000000000000006044820152606401610ce0565b610de033838561437a565b336000908152600e602052604090205460ff16612ddc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c69642070726f7879000000000000000000000000000000000000006044820152606401610ce0565b336000818152600f6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8681168552908352818420805460ff8116157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009091161790556023909252909120541603612eba5773ffffffffffffffffffffffffffffffffffffffff8116600090815260236020908152604080832080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055601e8252808320543384529180528220805491929091612ab4908490615130565b50565b60245460ff610100909104161515600114612f34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4e6f7420696e206d6967726174696f6e000000000000000000000000000000006044820152606401610ce0565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260226020908152604080832033845290915290205460ff168015612f8357503360009081526021602052604090205460ff165b612fe9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d69672e20696e76616c6964206f7220756e617070726f7665640000000000006044820152606401610ce0565b611cbc82338361437a565b6000806012838154811061300a5761300a6150d2565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905080156130e557670de0b6b3a7640000601a8481548110613050576130506150d2565b90600052602060002001548273ffffffffffffffffffffffffffffffffffffffff16630a3be7576040518163ffffffff1660e01b8152600401602060405180830381865afa1580156130a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130ca919061522c565b6130d49190615147565b6130de9190615184565b9150610b78565b601483815481106130f8576130f86150d2565b9060005260206000200154915050919050565b60005b6012548110156132dd5760006012828154811061312d5761312d6150d2565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905080156132ca57828061317f5750601b8281548110613171576131716150d2565b906000526020600020015442115b156132ca576040517f6472eee100000000000000000000000000000000000000000000000000000000815230600482015242602482015273ffffffffffffffffffffffffffffffffffffffff821690636472eee1906044016020604051808303816000875af11580156131f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061321a919061522c565b601a838154811061322d5761322d6150d2565b90600052602060002001819055508073ffffffffffffffffffffffffffffffffffffffff1663513872bd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613286573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132aa919061522c565b601b83815481106132bd576132bd6150d2565b6000918252602090912001555b50806132d5816151d7565b91505061310e565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff1633148061331a5750738412ebf45bac1b340bbe8f318b928c466c4e39ca33145b613380576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4e6f74206f776e6572206f722074696d656c6f636b00000000000000000000006044820152606401610ce0565b8051670de0b6b3a764000011156133f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4d757374206265203e3d204d554c2050524543000000000000000000000000006044820152606401610ce0565b608081015160011180159061340d575060a0810151600111155b613473576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4d757374206265203e3d203100000000000000000000000000000000000000006044820152606401610ce0565b80516007556020810151600b556040810151600c556060810151600a55608081015160085560a00151600955565b6134ab600061310b565b670de0b6b3a764000060045560055442106134ca576134c861468a565b565b6134c8614b3f565b60008183106134e157816134e3565b825b9392505050565b60008560016134f98282613cc5565b602454640100000000900460ff16158061352757503360009081526021602052604090205460ff1615156001145b61358d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f5374616b696e6720706175736564206f7220696e206d6967726174696f6e00006044820152606401610ce0565b6009548510156135f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d696e696d756d207374616b652074696d65206e6f74206d65740000000000006044820152606401610ce0565b600854851115613665576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f547279696e6720746f206c6f636b20666f7220746f6f206c6f6e6700000000006044820152606401610ce0565b6024546136939065010000000000900473ffffffffffffffffffffffffffffffffffffffff168830896141dc565b600061369e86610b7e565b73ffffffffffffffffffffffffffffffffffffffff8a166000908152601e602090815260408083205490517fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608f901b169281019290925260348201899052605482018b9052607482015291925090609401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012073ffffffffffffffffffffffffffffffffffffffff8e1660009081526026835283902060a0850184528185529184018a90529183018b905290925090606081016137918a8a6151bf565b81526020908101859052825460018181018555600094855293829020835160059092020190815590820151928101929092556040810151600283015560608101516003830155608001516004909101556137e9610f86565b600082815260256020526040812091909155601c80548a929061380d9084906151bf565b909155505073ffffffffffffffffffffffffffffffffffffffff8a166000908152601e6020526040812080548a92906138479084906151bf565b90915550600090506138588b612555565b905073ffffffffffffffffffffffffffffffffffffffff8116156138b05773ffffffffffffffffffffffffffffffffffffffff81166000908152602080526040812080548b92906138aa9084906151bf565b90915550505b506138bc8a6000613cc5565b604080518981526020810189905290810182905273ffffffffffffffffffffffffffffffffffffffff8a811660608301528b16907ff400e72e69ef4402819dfc57eeddc66f5eb69bf405e0e8098b1946ec1ac14a229060800160405180910390a29998505050505050505050565b60006110bd426005546134d2565b60608360016139478282613cc5565b6024546301000000900460ff16156139bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f5265776172647320636f6c6c656374696f6e20706175736564000000000000006044820152606401610ce0565b60115467ffffffffffffffff8111156139d6576139d6614ffe565b6040519080825280602002602001820160405280156139ff578160200160208202803683370190505b50925060005b601154811015613b295773ffffffffffffffffffffffffffffffffffffffff871660009081526018602090815260408083208484529091529020548451859083908110613a5457613a546150d2565b60209081029190910181019190915273ffffffffffffffffffffffffffffffffffffffff881660009081526018825260408082208483529092529081208190558451859083908110613aa857613aa86150d2565b60200260200101511115613b1757613b1760118281548110613acc57613acc6150d2565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1687868481518110613b0a57613b0a6150d2565b6020026020010151613b5c565b80613b21816151d7565b915050613a05565b50505073ffffffffffffffffffffffffffffffffffffffff90931660009081526019602052604090204290555090919050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790529151600092839290871691613bf39190615271565b6000604051808303816000865af19150503d8060008114613c30576040519150601f19603f3d011682016040523d82523d6000602084013e613c35565b606091505b5091509150818015613c5f575080511580613c5f575080806020019051810190613c5f919061528d565b611269576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c4544006044820152606401610ce0565b8015613cd357613cd36134a1565b73ffffffffffffffffffffffffffffffffffffffff8216156132dd576000806000613cfd85611cc1565b925092509250613d0c85614bb2565b73ffffffffffffffffffffffffffffffffffffffff85166000908152600d60205260409020829055828110613d90576000613d478483615130565b905080601d54613d5791906151bf565b601d55613d6481856151bf565b73ffffffffffffffffffffffffffffffffffffffff87166000908152601f602052604090205550611269565b6000613d9c8285615130565b905080601d54613dac9190615130565b601d55613db98185615130565b73ffffffffffffffffffffffffffffffffffffffff87166000908152601f6020526040902055505050505050565b613e1c6040518060a0016040528060008019168152602001600081526020016000815260200160008152602001600081525090565b6000805b73ffffffffffffffffffffffffffffffffffffffff8516600090815260266020526040902054811015613f3a5773ffffffffffffffffffffffffffffffffffffffff85166000908152602660205260409020805482908110613e8457613e846150d2565b9060005260206000209060050201600001548403613f285773ffffffffffffffffffffffffffffffffffffffff85166000908152602660205260409020805482908110613ed357613ed36150d2565b90600052602060002090600502016040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815250509250809150613f3a565b80613f32816151d7565b915050613e20565b5081518314613fa5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5374616b65206e6f7420666f756e6400000000000000000000000000000000006044820152606401610ce0565b9250929050565b613fe16040518060a0016040528060008019168152602001600081526020016000815260200160008152602001600081525090565b82516000908152602560205260408120548190613ffc610f86565b866040015161400b9190615147565b6140159190615184565b905060008560400151826140299190615130565b73ffffffffffffffffffffffffffffffffffffffff881660009081526026602052604090208054919250839187908110614065576140656150d2565b90600052602060002090600502016002018190555080601c600082825461408c91906151bf565b909155505073ffffffffffffffffffffffffffffffffffffffff87166000908152601e6020526040812080548392906140c69084906151bf565b90915550600090506140d788612555565b905073ffffffffffffffffffffffffffffffffffffffff81161561412f5773ffffffffffffffffffffffffffffffffffffffff81166000908152602080526040812080548492906141299084906151bf565b90915550505b50614138610f86565b865160009081526025602090815260408083209390935573ffffffffffffffffffffffffffffffffffffffff8a168252602690522080548690811061417f5761417f6150d2565b906000526020600020906005020185816040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815250509150935093505050935093915050565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052915160009283929088169161427b9190615271565b6000604051808303816000865af19150503d80600081146142b8576040519150601f19603f3d011682016040523d82523d6000602084013e6142bd565b606091505b50915091508180156142e75750805115806142e75750808060200190518101906142e7919061528d565b614372576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f5472616e7366657248656c7065723a205452414e534645525f46524f4d5f464160448201527f494c4544000000000000000000000000000000000000000000000000000000006064820152608401610ce0565b505050505050565b600061438884846001613938565b506000806143968685613de7565b915091506143a5868383613fac565b506060810151909250421015806143c3575060245460ff1615156001145b806143e257503360009081526021602052604090205460ff1615156001145b614448576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616b65206973207374696c6c206c6f636b656421000000000000000000006044820152606401610ce0565b604082015180156146805780601c60008282546144659190615130565b909155505073ffffffffffffffffffffffffffffffffffffffff87166000908152601e60205260408120805483929061449f908490615130565b90915550600090506144b088612555565b905073ffffffffffffffffffffffffffffffffffffffff8116156145085773ffffffffffffffffffffffffffffffffffffffff8116600090815260208052604081208054849290614502908490615130565b90915550505b5073ffffffffffffffffffffffffffffffffffffffff87166000908152602660205260409020805483908110614540576145406150d2565b60009182526020822060059190910201818155600181018290556002810182905560038101829055600490810191909155602480546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a8116948201949094529182018490526501000000000090049091169063a9059cbb906044016020604051808303816000875af11580156145f5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614619919061528d565b50614625876000613cc5565b604080518281526020810187905273ffffffffffffffffffffffffffffffffffffffff888116828401529151918916917f1d9308f6b22a2754a1c622bb30889e8f8f956c83e524d039e9d65d5f052eb9089181900360600190a25b9695505050505050565b60005b60135481101561477b576000601382815481106146ac576146ac6150d2565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1690508015614768576040517f092193ab00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff82169063092193ab9060240160408051808303816000875af1158015614741573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061476591906152aa565b50505b5080614773816151d7565b91505061468d565b50600062093a80600554426147909190615130565b61479a9190615184565b905060005b60115481101561497d57601181815481106147bc576147bc6150d2565b6000918252602090912001546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015614833573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614857919061522c565b6148628360016151bf565b62093a8061486f84612ff4565b6148799190615147565b6148839190615147565b111560118281548110614898576148986150d2565b60009182526020918290200154604080517f4e6f7420656e6f7567682072657761726420746f6b656e7320617661696c6162938101939093527f6c653a20000000000000000000000000000000000000000000000000000000009083015260601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660448201526058016040516020818303038152906040529061496a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce091906152ce565b5080614975816151d7565b91505061479f565b5062093a8061498d8260016151bf565b6149979190615147565b6005546149a491906151bf565b6005556149af614b3f565b670de0b6b3a76400006004556014805460019081106149d0576149d06150d2565b9060005260206000200154600014612eba576040805160018082528183019092526000916020808301908036833701905050905073d4937682df3c8aef4fe912a96a74121c0829e66481600081518110614a2c57614a2c6150d2565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526040517f3111e7b300000000000000000000000000000000000000000000000000000000815260009073d784927ff2f95ba542bfc824c8a8a98f3495f6b590633111e7b390614ac89085907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90309060040161531f565b6020604051808303816000875af1158015614ae7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b0b919061522c565b9050614b1a62093a8082615184565b6014600181548110614b2e57614b2e6150d2565b600091825260209091200155505050565b6000614b4961174d565b905060005b601654811015614ba357818181518110614b6a57614b6a6150d2565b602002602001015160168281548110614b8557614b856150d2565b60009182526020909120015580614b9b816151d7565b915050614b4e565b50614bac61392a565b60065550565b73ffffffffffffffffffffffffffffffffffffffff811615612eba576000614bd9826109ff565b905060005b8151811015614c4757818181518110614bf957614bf96150d2565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff85166000908152601883526040808220858352909352919091205580614c3f816151d7565b915050614bde565b5060005b8151811015611cbc5760168181548110614c6757614c676150d2565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff8616835260178252604080842085855290925291205580614caa816151d7565b915050614c4b565b73ffffffffffffffffffffffffffffffffffffffff81168114612eba57600080fd5b600060208284031215614ce657600080fd5b81356134e381614cb2565b6020808252825182820181905260009190848201906040850190845b81811015614d2957835183529284019291840191600101614d0d565b50909695505050505050565b600060208284031215614d4757600080fd5b5035919050565b600081518084526020808501945080840160005b83811015614d9457815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101614d62565b509495945050505050565b6020815260006134e36020830184614d4e565b60008060408385031215614dc557600080fd5b50508035926020909101359150565b602080825282518282018190526000919060409081850190868401855b82811015614e355781518051855286810151878601528581015186860152606080820151908601526080908101519085015260a09093019290850190600101614df1565b5091979650505050505050565b60008060408385031215614e5557600080fd5b8235614e6081614cb2565b91506020830135614e7081614cb2565b809150509250929050565b60008060008060808587031215614e9157600080fd5b8435614e9c81614cb2565b966020860135965060408601359560600135945092505050565b8015158114612eba57600080fd5b60008060408385031215614ed757600080fd5b8235614ee281614cb2565b91506020830135614e7081614eb6565b60008060408385031215614f0557600080fd5b8235614f1081614cb2565b946020939093013593505050565b600080600060608486031215614f3357600080fd5b8335614f3e81614eb6565b92506020840135614f4e81614eb6565b91506040840135614f5e81614eb6565b809150509250925092565b60008060008060808587031215614f7f57600080fd5b8435614f8a81614cb2565b9350602085013592506040850135614fa181614cb2565b91506060850135614fb181614cb2565b939692955090935050565b60008060408385031215614fcf57600080fd5b823591506020830135614e7081614cb2565b600060208284031215614ff357600080fd5b81356134e381614eb6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060c0828403121561503f57600080fd5b82601f83011261504e57600080fd5b60405160c0810181811067ffffffffffffffff82111715615098577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040528060c08401858111156150ad57600080fd5b845b818110156150c75780358352602092830192016150af565b509195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561514257615142615101565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561517f5761517f615101565b500290565b6000826151ba577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600082198211156151d2576151d2615101565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361520857615208615101565b5060010190565b60006020828403121561522157600080fd5b81516134e381614cb2565b60006020828403121561523e57600080fd5b5051919050565b60005b83811015615260578181015183820152602001615248565b83811115611c545750506000910152565b60008251615283818460208701615245565b9190910192915050565b60006020828403121561529f57600080fd5b81516134e381614eb6565b600080604083850312156152bd57600080fd5b505080516020909101519092909150565b60208152600082518060208401526152ed816040850160208701615245565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6060815260006153326060830186614d4e565b905083602083015273ffffffffffffffffffffffffffffffffffffffff8316604083015294935050505056fea264697066735822122062234020a79da5894696814a693b51a31d672a6e51f17fa40d3cc3868dc56bea64736f6c634300080d0033000000000000000000000000ff5b4bcbf765fe363269114e1c765229a29edefd00000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000260000000000000000000000000d4937682df3c8aef4fe912a96a74121c0829e66400000000000000000000000000000000000000000000000000000000000000020000000000000000000000003432b6a60d23ca0dfca7761b7ab56459d9c964d00000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f50000000000000000000000000000000000000000000000000000000000000002000000000000000000000000b1748c79709f4ba2dd82834b8c82d4a505003f27000000000000000000000000b1748c79709f4ba2dd82834b8c82d4a505003f27000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000a86cc92e3da00000000000000000000000000000000000000000000000000000002b1de5ada0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000278dc748eda1d8efef1adfb518542612b49fcd340000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106104205760003560e01c80638da5cb5b11610235578063d42fc9b411610135578063e7f30582116100c8578063f2a8d34911610097578063f77e34d11161007c578063f77e34d1146109d1578063facefb64146109e4578063fff6cae9146109f757600080fd5b8063f2a8d349146109b5578063f2caeb1e146109be57600080fd5b8063e7f305821461097d578063eb3c209e14610990578063ebe2b12b146109a3578063f288baf6146109ac57600080fd5b8063de1a655111610104578063de1a655114610947578063e01f62bf1461095a578063e1ba95d214610962578063e44b9fa51461096a57600080fd5b8063d42fc9b4146108d8578063d5e1a9c6146108eb578063d7400d56146108fe578063d9f96e8d1461091157600080fd5b8063b94c4dcb116101c8578063c8f33c9111610197578063cc2abd641161017c578063cc2abd64146108b3578063cdc82e80146108c6578063d2010fb4146108cf57600080fd5b8063c8f33c9114610874578063ca6df29d1461087d57600080fd5b8063b94c4dcb14610825578063b9ec92231461082e578063c00007b01461084e578063c35438261461086157600080fd5b8063a2217bc511610204578063a2217bc5146107ee578063aa1d4fce146107f6578063affaa7a4146107ff578063b85efd061461081257600080fd5b80638da5cb5b1461079b57806391cf600a146107bb5780639637927f146107ce578063a0f23476146107db57600080fd5b8063387edc861161034057806370641a36116102d357806379ba5097116102a25780637f472e54116102875780637f472e54146107475780638980f11f1461075a5780638bad86a71461076d57600080fd5b806379ba5097146107205780637d6ef08e1461072857600080fd5b806370641a36146106a157806372f702f3146106a95780637910d17b146106d25780637970833e146106e557600080fd5b80635bfd92581161030f5780635bfd92581461066257806364f2c0601461067057806369339245146106785780636e27cef91461069857600080fd5b8063387edc86146105e657806341a16f3f146105f95780634fd2b5361461062f57806353a47bb71461064257600080fd5b8063215951e2116103b85780632c0c2a0a116103875780632c0c2a0a146105805780633650aff21461059357806336f89af2146105a6578063386a9525146105dc57600080fd5b8063215951e2146104e7578063231b68dc146104ef57806328408bab1461051257806328ef934e1461056d57600080fd5b806317b18c89116103f457806317b18c89146104995780631c1f78eb146104ac5780631e090f01146104b45780631face856146104d457600080fd5b80628cc262146104255780630d7bac4f1461044e57806312edb24c1461046f5780631627540c14610484575b600080fd5b610438610433366004614cd4565b6109ff565b6040516104459190614cf1565b60405180910390f35b61046161045c366004614d35565b610b7e565b604051908152602001610445565b610477610bce565b6040516104459190614d9f565b610497610492366004614cd4565b610c3d565b005b6104616104a7366004614db2565b610d62565b610438610dec565b6104c76104c2366004614cd4565b610e8d565b6040516104459190614dd4565b6104616104e2366004614cd4565b610f41565b610461610f86565b6105026104fd366004614e42565b6110c2565b6040519015158152602001610445565b610548610520366004614cd4565b60236020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610445565b61049761057b366004614e7b565b611130565b61046161058e366004614cd4565b611270565b6104976105a1366004614cd4565b61154e565b6104616105b4366004614cd4565b73ffffffffffffffffffffffffffffffffffffffff166000908152601f602052604090205490565b61046162093a8081565b6104976105f4366004614cd4565b611641565b610548610607366004614cd4565b60106020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b61046161063d366004614cd4565b61172c565b6001546105489073ffffffffffffffffffffffffffffffffffffffff1681565b670de0b6b3a7640000610461565b601d54610461565b610461610686366004614cd4565b60156020526000908152604090205481565b61046160095481565b61043861174d565b6024546105489065010000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b6104386106e0366004614ec4565b6118ac565b6106f86106f3366004614ef2565b611928565b604080519586526020860194909452928401919091526060830152608082015260a001610445565b610497611976565b610461610736366004614cd4565b602080526000908152604090205481565b610461610755366004614cd4565b611ac1565b610497610768366004614ef2565b611ad8565b61078061077b366004614cd4565b611cc1565b60408051938452602084019290925290820152606001610445565b6000546105489073ffffffffffffffffffffffffffffffffffffffff1681565b6104976107c9366004614cd4565b611f8f565b6024546105029060ff1681565b6104616107e9366004614cd4565b612082565b61049761213d565b610461600a5481565b61049761080d366004614cd4565b612216565b610497610820366004614db2565b612306565b61046160085481565b61046161083c366004614d35565b60256020526000908152604090205481565b61043861085c366004614cd4565b6124cd565b61054861086f366004614cd4565b612555565b61046160065481565b61046161088b366004614cd4565b73ffffffffffffffffffffffffffffffffffffffff1660009081526026602052604090205490565b6104976108c1366004614f1e565b6125b3565b61046160075481565b61046160045481565b6104616108e6366004614cd4565b6126ec565b6104976108f9366004614f69565b612728565b61049761090c366004614cd4565b612917565b61046161091f366004614cd4565b73ffffffffffffffffffffffffffffffffffffffff166000908152601e602052604090205490565b610497610955366004614e42565b612abc565b601c54610461565b610497612ba3565b610461610978366004614fbc565b612c74565b61049761098b366004614cd4565b612d63565b61049761099e366004614ef2565b612ebd565b61046160055481565b610461600b5481565b610461600c5481565b6104616109cc366004614d35565b612ff4565b6104976109df366004614fe1565b61310b565b6104976109f236600461502d565b6132e1565b6104976134a1565b60606000610a0b61174d565b60115490915067ffffffffffffffff811115610a2957610a29614ffe565b604051908082528060200260200182016040528015610a52578160200160208202803683370190505b5073ffffffffffffffffffffffffffffffffffffffff84166000908152601f602052604090205490925015610b785760005b601154811015610b765773ffffffffffffffffffffffffffffffffffffffff84166000818152601860209081526040808320858452825280832054938352601782528083208584529091529020548351670de0b6b3a76400009190859085908110610af157610af16150d2565b6020026020010151610b039190615130565b73ffffffffffffffffffffffffffffffffffffffff87166000908152601f6020526040902054610b339190615147565b610b3d9190615184565b610b4791906151bf565b838281518110610b5957610b596150d2565b602090810291909101015280610b6e816151d7565b915050610a84565b505b50919050565b600754600854600091610bc891610b9d670de0b6b3a764000083615130565b610ba79086615147565b610bb19190615184565b610bc390670de0b6b3a76400006151bf565b6134d2565b92915050565b60606011805480602002602001604051908101604052809291908181526020018280548015610c3357602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610c08575b5050505050905090565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ce9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201527f6f726d207468697320616374696f6e000000000000000000000000000000000060648201526084015b60405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229060200160405180910390a150565b60006002805403610dcf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610ce0565b60028055610de033808585426134ea565b60016002559392505050565b60145460609067ffffffffffffffff811115610e0a57610e0a614ffe565b604051908082528060200260200182016040528015610e33578160200160208202803683370190505b50905060005b601454811015610e895762093a80610e5082612ff4565b610e5a9190615147565b828281518110610e6c57610e6c6150d2565b602090810291909101015280610e81816151d7565b915050610e39565b5090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152602660209081526040808320805482518185028101850190935280835260609492939192909184015b82821015610f3657838290600052602060002090600502016040518060a00160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152505081526020019060010190610ed2565b505050509050919050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152602080526040812054600454670de0b6b3a764000091610f7c91615147565b610bc89190615184565b6000602460059054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637535d2466040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ff5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611019919061520f565b6040517fd15e005300000000000000000000000000000000000000000000000000000000815273853d955acef822db058eb8505911ed77f175b99e600482015273ffffffffffffffffffffffffffffffffffffffff919091169063d15e005390602401602060405180830381865afa158015611099573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110bd919061522c565b905090565b6000805473ffffffffffffffffffffffffffffffffffffffff908116908416036110ee57506001610bc8565b73ffffffffffffffffffffffffffffffffffffffff82811660009081526010602052604090205481851691160361112757506001610bc8565b50600092915050565b60245460ff6101009091041615156001146111a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4e6f7420696e206d6967726174696f6e000000000000000000000000000000006044820152606401610ce0565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260226020908152604080832033845290915290205460ff1680156111f657503360009081526021602052604090205460ff165b61125c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d69672e20696e76616c6964206f7220756e617070726f7665640000000000006044820152606401610ce0565b61126984338585856134ea565b5050505050565b6000808061127d84612555565b905073ffffffffffffffffffffffffffffffffffffffff811615611334576003546040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152909116906370a0823190602401602060405180830381865afa15801561130b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061132f919061522c565b6113c8565b6003546040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152909116906370a0823190602401602060405180830381865afa1580156113a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c8919061522c565b91506000670de0b6b3a7640000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611442573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611466919061522c565b6114709190615147565b600a54600b546114809086615147565b61148a9190615147565b6114949190615184565b905060008073ffffffffffffffffffffffffffffffffffffffff8416156114c3576114be84611ac1565b6114cc565b6114cc8761172c565b9050801561151e576000816114e9670de0b6b3a764000088615147565b6114f39190615184565b9050670de0b6b3a7640000600b548261150c9190615147565b6115169190615184565b925050611523565b600091505b508082116115315780611533565b815b9450600b5485111561154557600b5494505b50505050919050565b60005473ffffffffffffffffffffffffffffffffffffffff163314806115875750738412ebf45bac1b340bbe8f318b928c466c4e39ca33145b6115ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4e6f74206f776e6572206f722074696d656c6f636b00000000000000000000006044820152606401610ce0565b73ffffffffffffffffffffffffffffffffffffffff16600090815260216020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b60028054036116ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610ce0565b600280556024546301000000900460ff1615611724576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f5265776172647320636f6c6c656374696f6e20706175736564000000000000006044820152606401610ce0565b506001600255565b6000670de0b6b3a7640000600c54611743846126ec565b610f7c9190615147565b6060601c54600014806117605750601d54155b156117ba576016805480602002602001604051908101604052809291908181526020018280548015610c3357602002820191906000526020600020905b81548152602001906001019080831161179d575050505050905090565b60115467ffffffffffffffff8111156117d5576117d5614ffe565b6040519080825280602002602001820160405280156117fe578160200160208202803683370190505b50905060005b601654811015610e8957601d5461181a82612ff4565b60065461182561392a565b61182f9190615130565b6118399190615147565b61184b90670de0b6b3a7640000615147565b6118559190615184565b60168281548110611868576118686150d2565b906000526020600020015461187d91906151bf565b82828151811061188f5761188f6150d2565b6020908102919091010152806118a4816151d7565b915050611804565b60606002805403611919576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610ce0565b60028055610de0338484613938565b6026602052816000526040600020818154811061194457600080fd5b600091825260209091206005909102018054600182015460028301546003840154600490940154929550909350919085565b60015473ffffffffffffffffffffffffffffffffffffffff163314611a1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527f2063616e20616363657074206f776e65727368697000000000000000000000006064820152608401610ce0565b6000546001546040805173ffffffffffffffffffffffffffffffffffffffff93841681529290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a160018054600080547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff841617909155169055565b6000670de0b6b3a7640000600c5461174384610f41565b600054829073ffffffffffffffffffffffffffffffffffffffff16331480611b055750611b0533826110c2565b611b6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f74206f776e6572206f7220746b6e206d67720000000000000000000000006044820152606401610ce0565b6000805b601154811015611be5578473ffffffffffffffffffffffffffffffffffffffff1660118281548110611ba357611ba36150d2565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1603611bd35760019150611be5565b80611bdd816151d7565b915050611b6f565b50808015611c19575073ffffffffffffffffffffffffffffffffffffffff8481166000908152601060205260409020541633145b80611c44575080158015611c44575060005473ffffffffffffffffffffffffffffffffffffffff1633145b15611c5a57611c54843385613b5c565b50505050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4e6f2076616c696420746f6b656e7320746f207265636f7665720000000000006044820152606401610ce0565b505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152601f60205260408120549080611cf284611270565b73ffffffffffffffffffffffffffffffffffffffff85166000908152601e602052604081205491935090158015611d4c575073ffffffffffffffffffffffffffffffffffffffff85166000908152601f6020526040902054155b15611d58575081611d98565b73ffffffffffffffffffffffffffffffffffffffff85166000908152600d6020526040902054600290611d8b90856151bf565b611d959190615184565b90505b6000915060005b73ffffffffffffffffffffffffffffffffffffffff8616600090815260266020526040902054811015611f865773ffffffffffffffffffffffffffffffffffffffff86166000908152602660205260408120805483908110611e0357611e036150d2565b90600052602060002090600502016040518060a001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481525050905060008160800151905042826060015111611f3357606082015173ffffffffffffffffffffffffffffffffffffffff89166000908152601960205260409020541015611f285773ffffffffffffffffffffffffffffffffffffffff88166000908152601960205260408120546060840151611eca9190615130565b90506000836060015142611ede9190615130565b90506000611ef482670de0b6b3a7640000615147565b611efe8486615147565b611f0891906151bf565b9050611f1482846151bf565b611f1e9082615184565b9350505050611f33565b50670de0b6b3a76400005b60408201516000670de0b6b3a7640000611f4d87856151bf565b611f579084615147565b611f619190615184565b9050611f6d81886151bf565b9650505050508080611f7e906151d7565b915050611d9f565b50509193909250565b60005473ffffffffffffffffffffffffffffffffffffffff16331480611fc85750738412ebf45bac1b340bbe8f318b928c466c4e39ca33145b61202e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4e6f74206f776e6572206f722074696d656c6f636b00000000000000000000006044820152606401610ce0565b73ffffffffffffffffffffffffffffffffffffffff166000908152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b6000600454600c546120949190615147565b6003546040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152670de0b6b3a76400009283929116906370a0823190602401602060405180830381865afa15801561210f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612133919061522c565b6117439190615147565b60005473ffffffffffffffffffffffffffffffffffffffff163314806121765750738412ebf45bac1b340bbe8f318b928c466c4e39ca33145b6121dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4e6f74206f776e6572206f722074696d656c6f636b00000000000000000000006044820152606401610ce0565b602480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff81166101009182900460ff1615909102179055565b73ffffffffffffffffffffffffffffffffffffffff811660009081526021602052604090205460ff166122a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f496e76616c6964206d69677261746f72206164647265737300000000000000006044820152606401610ce0565b33600090815260226020908152604080832073ffffffffffffffffffffffffffffffffffffffff94909416835292905220805460ff8116157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909116179055565b3360016123138282613cc5565b6000806123203387613de7565b9150915061232f338383613fac565b5091506000859003612342575050611c54565b600085836040015161235491906151bf565b90506024546123849065010000000000900473ffffffffffffffffffffffffffffffffffffffff163330896141dc565b6040805160a0810182528881526020858101518183015281830184905260608087015190830152608080870151908301523360009081526026909152919091208054849081106123d6576123d66150d2565b9060005260206000209060050201600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015590505085601c600082825461242b91906151bf565b9091555050336000908152601e60205260408120805488929061244f9084906151bf565b909155506000905061246033612555565b905073ffffffffffffffffffffffffffffffffffffffff8116156124b85773ffffffffffffffffffffffffffffffffffffffff81166000908152602080526040812080548992906124b29084906151bf565b90915550505b506124c4336000613cc5565b50505050505050565b6060600280540361253a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610ce0565b6002805561254a33836001613938565b600160025592915050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600e602052604081205460ff1615612587575090565b5073ffffffffffffffffffffffffffffffffffffffff9081166000908152602360205260409020541690565b60005473ffffffffffffffffffffffffffffffffffffffff163314806125ec5750738412ebf45bac1b340bbe8f318b928c466c4e39ca33145b612652576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4e6f74206f776e6572206f722074696d656c6f636b00000000000000000000006044820152606401610ce0565b602480549115156301000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffff93151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff95151564010000000002959095167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff00ffff909316929092179390931791909116179055565b73ffffffffffffffffffffffffffffffffffffffff81166000908152601e6020526040812054600454670de0b6b3a764000091610f7c91615147565b600054849073ffffffffffffffffffffffffffffffffffffffff16331480612755575061275533826110c2565b6127bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f74206f776e6572206f7220746b6e206d67720000000000000000000000006044820152606401610ce0565b73ffffffffffffffffffffffffffffffffffffffff85166000908152601560205260409020546014805486929081106127f6576127f66150d2565b9060005260206000200181905550826012601560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205481548110612857576128576150d2565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9485161790559187168152601590915260409020546013805484929081106128c8576128c86150d2565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600e602052604090205460ff166129a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c69642070726f7879000000000000000000000000000000000000006044820152606401610ce0565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600f6020908152604080832033845290915290205460ff16612a40576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f50726f787920686173206e6f7420616c6c6f77656420796f75207965740000006044820152606401610ce0565b33600090815260236020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616908117909155601e8352818420549084529180528220805491929091612ab49084906151bf565b909155505050565b600054829073ffffffffffffffffffffffffffffffffffffffff16331480612ae95750612ae933826110c2565b612b4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f74206f776e6572206f7220746b6e206d67720000000000000000000000006044820152606401610ce0565b5073ffffffffffffffffffffffffffffffffffffffff918216600090815260106020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001691909216179055565b60005473ffffffffffffffffffffffffffffffffffffffff16331480612bdc5750738412ebf45bac1b340bbe8f318b928c466c4e39ca33145b612c42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4e6f74206f776e6572206f722074696d656c6f636b00000000000000000000006044820152606401610ce0565b602480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b60006002805403612ce1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610ce0565b6002805560245462010000900460ff1615612d58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f5769746864726177616c732070617573656400000000000000000000000000006044820152606401610ce0565b610de033838561437a565b336000908152600e602052604090205460ff16612ddc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c69642070726f7879000000000000000000000000000000000000006044820152606401610ce0565b336000818152600f6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8681168552908352818420805460ff8116157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009091161790556023909252909120541603612eba5773ffffffffffffffffffffffffffffffffffffffff8116600090815260236020908152604080832080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055601e8252808320543384529180528220805491929091612ab4908490615130565b50565b60245460ff610100909104161515600114612f34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4e6f7420696e206d6967726174696f6e000000000000000000000000000000006044820152606401610ce0565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260226020908152604080832033845290915290205460ff168015612f8357503360009081526021602052604090205460ff165b612fe9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d69672e20696e76616c6964206f7220756e617070726f7665640000000000006044820152606401610ce0565b611cbc82338361437a565b6000806012838154811061300a5761300a6150d2565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905080156130e557670de0b6b3a7640000601a8481548110613050576130506150d2565b90600052602060002001548273ffffffffffffffffffffffffffffffffffffffff16630a3be7576040518163ffffffff1660e01b8152600401602060405180830381865afa1580156130a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130ca919061522c565b6130d49190615147565b6130de9190615184565b9150610b78565b601483815481106130f8576130f86150d2565b9060005260206000200154915050919050565b60005b6012548110156132dd5760006012828154811061312d5761312d6150d2565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905080156132ca57828061317f5750601b8281548110613171576131716150d2565b906000526020600020015442115b156132ca576040517f6472eee100000000000000000000000000000000000000000000000000000000815230600482015242602482015273ffffffffffffffffffffffffffffffffffffffff821690636472eee1906044016020604051808303816000875af11580156131f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061321a919061522c565b601a838154811061322d5761322d6150d2565b90600052602060002001819055508073ffffffffffffffffffffffffffffffffffffffff1663513872bd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613286573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132aa919061522c565b601b83815481106132bd576132bd6150d2565b6000918252602090912001555b50806132d5816151d7565b91505061310e565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff1633148061331a5750738412ebf45bac1b340bbe8f318b928c466c4e39ca33145b613380576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4e6f74206f776e6572206f722074696d656c6f636b00000000000000000000006044820152606401610ce0565b8051670de0b6b3a764000011156133f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4d757374206265203e3d204d554c2050524543000000000000000000000000006044820152606401610ce0565b608081015160011180159061340d575060a0810151600111155b613473576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4d757374206265203e3d203100000000000000000000000000000000000000006044820152606401610ce0565b80516007556020810151600b556040810151600c556060810151600a55608081015160085560a00151600955565b6134ab600061310b565b670de0b6b3a764000060045560055442106134ca576134c861468a565b565b6134c8614b3f565b60008183106134e157816134e3565b825b9392505050565b60008560016134f98282613cc5565b602454640100000000900460ff16158061352757503360009081526021602052604090205460ff1615156001145b61358d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f5374616b696e6720706175736564206f7220696e206d6967726174696f6e00006044820152606401610ce0565b6009548510156135f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d696e696d756d207374616b652074696d65206e6f74206d65740000000000006044820152606401610ce0565b600854851115613665576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f547279696e6720746f206c6f636b20666f7220746f6f206c6f6e6700000000006044820152606401610ce0565b6024546136939065010000000000900473ffffffffffffffffffffffffffffffffffffffff168830896141dc565b600061369e86610b7e565b73ffffffffffffffffffffffffffffffffffffffff8a166000908152601e602090815260408083205490517fffffffffffffffffffffffffffffffffffffffff00000000000000000000000060608f901b169281019290925260348201899052605482018b9052607482015291925090609401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012073ffffffffffffffffffffffffffffffffffffffff8e1660009081526026835283902060a0850184528185529184018a90529183018b905290925090606081016137918a8a6151bf565b81526020908101859052825460018181018555600094855293829020835160059092020190815590820151928101929092556040810151600283015560608101516003830155608001516004909101556137e9610f86565b600082815260256020526040812091909155601c80548a929061380d9084906151bf565b909155505073ffffffffffffffffffffffffffffffffffffffff8a166000908152601e6020526040812080548a92906138479084906151bf565b90915550600090506138588b612555565b905073ffffffffffffffffffffffffffffffffffffffff8116156138b05773ffffffffffffffffffffffffffffffffffffffff81166000908152602080526040812080548b92906138aa9084906151bf565b90915550505b506138bc8a6000613cc5565b604080518981526020810189905290810182905273ffffffffffffffffffffffffffffffffffffffff8a811660608301528b16907ff400e72e69ef4402819dfc57eeddc66f5eb69bf405e0e8098b1946ec1ac14a229060800160405180910390a29998505050505050505050565b60006110bd426005546134d2565b60608360016139478282613cc5565b6024546301000000900460ff16156139bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f5265776172647320636f6c6c656374696f6e20706175736564000000000000006044820152606401610ce0565b60115467ffffffffffffffff8111156139d6576139d6614ffe565b6040519080825280602002602001820160405280156139ff578160200160208202803683370190505b50925060005b601154811015613b295773ffffffffffffffffffffffffffffffffffffffff871660009081526018602090815260408083208484529091529020548451859083908110613a5457613a546150d2565b60209081029190910181019190915273ffffffffffffffffffffffffffffffffffffffff881660009081526018825260408082208483529092529081208190558451859083908110613aa857613aa86150d2565b60200260200101511115613b1757613b1760118281548110613acc57613acc6150d2565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1687868481518110613b0a57613b0a6150d2565b6020026020010151613b5c565b80613b21816151d7565b915050613a05565b50505073ffffffffffffffffffffffffffffffffffffffff90931660009081526019602052604090204290555090919050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790529151600092839290871691613bf39190615271565b6000604051808303816000865af19150503d8060008114613c30576040519150601f19603f3d011682016040523d82523d6000602084013e613c35565b606091505b5091509150818015613c5f575080511580613c5f575080806020019051810190613c5f919061528d565b611269576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c4544006044820152606401610ce0565b8015613cd357613cd36134a1565b73ffffffffffffffffffffffffffffffffffffffff8216156132dd576000806000613cfd85611cc1565b925092509250613d0c85614bb2565b73ffffffffffffffffffffffffffffffffffffffff85166000908152600d60205260409020829055828110613d90576000613d478483615130565b905080601d54613d5791906151bf565b601d55613d6481856151bf565b73ffffffffffffffffffffffffffffffffffffffff87166000908152601f602052604090205550611269565b6000613d9c8285615130565b905080601d54613dac9190615130565b601d55613db98185615130565b73ffffffffffffffffffffffffffffffffffffffff87166000908152601f6020526040902055505050505050565b613e1c6040518060a0016040528060008019168152602001600081526020016000815260200160008152602001600081525090565b6000805b73ffffffffffffffffffffffffffffffffffffffff8516600090815260266020526040902054811015613f3a5773ffffffffffffffffffffffffffffffffffffffff85166000908152602660205260409020805482908110613e8457613e846150d2565b9060005260206000209060050201600001548403613f285773ffffffffffffffffffffffffffffffffffffffff85166000908152602660205260409020805482908110613ed357613ed36150d2565b90600052602060002090600502016040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815250509250809150613f3a565b80613f32816151d7565b915050613e20565b5081518314613fa5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5374616b65206e6f7420666f756e6400000000000000000000000000000000006044820152606401610ce0565b9250929050565b613fe16040518060a0016040528060008019168152602001600081526020016000815260200160008152602001600081525090565b82516000908152602560205260408120548190613ffc610f86565b866040015161400b9190615147565b6140159190615184565b905060008560400151826140299190615130565b73ffffffffffffffffffffffffffffffffffffffff881660009081526026602052604090208054919250839187908110614065576140656150d2565b90600052602060002090600502016002018190555080601c600082825461408c91906151bf565b909155505073ffffffffffffffffffffffffffffffffffffffff87166000908152601e6020526040812080548392906140c69084906151bf565b90915550600090506140d788612555565b905073ffffffffffffffffffffffffffffffffffffffff81161561412f5773ffffffffffffffffffffffffffffffffffffffff81166000908152602080526040812080548492906141299084906151bf565b90915550505b50614138610f86565b865160009081526025602090815260408083209390935573ffffffffffffffffffffffffffffffffffffffff8a168252602690522080548690811061417f5761417f6150d2565b906000526020600020906005020185816040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820154815250509150935093505050935093915050565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052915160009283929088169161427b9190615271565b6000604051808303816000865af19150503d80600081146142b8576040519150601f19603f3d011682016040523d82523d6000602084013e6142bd565b606091505b50915091508180156142e75750805115806142e75750808060200190518101906142e7919061528d565b614372576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f5472616e7366657248656c7065723a205452414e534645525f46524f4d5f464160448201527f494c4544000000000000000000000000000000000000000000000000000000006064820152608401610ce0565b505050505050565b600061438884846001613938565b506000806143968685613de7565b915091506143a5868383613fac565b506060810151909250421015806143c3575060245460ff1615156001145b806143e257503360009081526021602052604090205460ff1615156001145b614448576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616b65206973207374696c6c206c6f636b656421000000000000000000006044820152606401610ce0565b604082015180156146805780601c60008282546144659190615130565b909155505073ffffffffffffffffffffffffffffffffffffffff87166000908152601e60205260408120805483929061449f908490615130565b90915550600090506144b088612555565b905073ffffffffffffffffffffffffffffffffffffffff8116156145085773ffffffffffffffffffffffffffffffffffffffff8116600090815260208052604081208054849290614502908490615130565b90915550505b5073ffffffffffffffffffffffffffffffffffffffff87166000908152602660205260409020805483908110614540576145406150d2565b60009182526020822060059190910201818155600181018290556002810182905560038101829055600490810191909155602480546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a8116948201949094529182018490526501000000000090049091169063a9059cbb906044016020604051808303816000875af11580156145f5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614619919061528d565b50614625876000613cc5565b604080518281526020810187905273ffffffffffffffffffffffffffffffffffffffff888116828401529151918916917f1d9308f6b22a2754a1c622bb30889e8f8f956c83e524d039e9d65d5f052eb9089181900360600190a25b9695505050505050565b60005b60135481101561477b576000601382815481106146ac576146ac6150d2565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1690508015614768576040517f092193ab00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff82169063092193ab9060240160408051808303816000875af1158015614741573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061476591906152aa565b50505b5080614773816151d7565b91505061468d565b50600062093a80600554426147909190615130565b61479a9190615184565b905060005b60115481101561497d57601181815481106147bc576147bc6150d2565b6000918252602090912001546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015614833573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614857919061522c565b6148628360016151bf565b62093a8061486f84612ff4565b6148799190615147565b6148839190615147565b111560118281548110614898576148986150d2565b60009182526020918290200154604080517f4e6f7420656e6f7567682072657761726420746f6b656e7320617661696c6162938101939093527f6c653a20000000000000000000000000000000000000000000000000000000009083015260601b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660448201526058016040516020818303038152906040529061496a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce091906152ce565b5080614975816151d7565b91505061479f565b5062093a8061498d8260016151bf565b6149979190615147565b6005546149a491906151bf565b6005556149af614b3f565b670de0b6b3a76400006004556014805460019081106149d0576149d06150d2565b9060005260206000200154600014612eba576040805160018082528183019092526000916020808301908036833701905050905073d4937682df3c8aef4fe912a96a74121c0829e66481600081518110614a2c57614a2c6150d2565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526040517f3111e7b300000000000000000000000000000000000000000000000000000000815260009073d784927ff2f95ba542bfc824c8a8a98f3495f6b590633111e7b390614ac89085907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90309060040161531f565b6020604051808303816000875af1158015614ae7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b0b919061522c565b9050614b1a62093a8082615184565b6014600181548110614b2e57614b2e6150d2565b600091825260209091200155505050565b6000614b4961174d565b905060005b601654811015614ba357818181518110614b6a57614b6a6150d2565b602002602001015160168281548110614b8557614b856150d2565b60009182526020909120015580614b9b816151d7565b915050614b4e565b50614bac61392a565b60065550565b73ffffffffffffffffffffffffffffffffffffffff811615612eba576000614bd9826109ff565b905060005b8151811015614c4757818181518110614bf957614bf96150d2565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff85166000908152601883526040808220858352909352919091205580614c3f816151d7565b915050614bde565b5060005b8151811015611cbc5760168181548110614c6757614c676150d2565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff8616835260178252604080842085855290925291205580614caa816151d7565b915050614c4b565b73ffffffffffffffffffffffffffffffffffffffff81168114612eba57600080fd5b600060208284031215614ce657600080fd5b81356134e381614cb2565b6020808252825182820181905260009190848201906040850190845b81811015614d2957835183529284019291840191600101614d0d565b50909695505050505050565b600060208284031215614d4757600080fd5b5035919050565b600081518084526020808501945080840160005b83811015614d9457815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101614d62565b509495945050505050565b6020815260006134e36020830184614d4e565b60008060408385031215614dc557600080fd5b50508035926020909101359150565b602080825282518282018190526000919060409081850190868401855b82811015614e355781518051855286810151878601528581015186860152606080820151908601526080908101519085015260a09093019290850190600101614df1565b5091979650505050505050565b60008060408385031215614e5557600080fd5b8235614e6081614cb2565b91506020830135614e7081614cb2565b809150509250929050565b60008060008060808587031215614e9157600080fd5b8435614e9c81614cb2565b966020860135965060408601359560600135945092505050565b8015158114612eba57600080fd5b60008060408385031215614ed757600080fd5b8235614ee281614cb2565b91506020830135614e7081614eb6565b60008060408385031215614f0557600080fd5b8235614f1081614cb2565b946020939093013593505050565b600080600060608486031215614f3357600080fd5b8335614f3e81614eb6565b92506020840135614f4e81614eb6565b91506040840135614f5e81614eb6565b809150509250925092565b60008060008060808587031215614f7f57600080fd5b8435614f8a81614cb2565b9350602085013592506040850135614fa181614cb2565b91506060850135614fb181614cb2565b939692955090935050565b60008060408385031215614fcf57600080fd5b823591506020830135614e7081614cb2565b600060208284031215614ff357600080fd5b81356134e381614eb6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060c0828403121561503f57600080fd5b82601f83011261504e57600080fd5b60405160c0810181811067ffffffffffffffff82111715615098577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040528060c08401858111156150ad57600080fd5b845b818110156150c75780358352602092830192016150af565b509195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561514257615142615101565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561517f5761517f615101565b500290565b6000826151ba577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600082198211156151d2576151d2615101565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361520857615208615101565b5060010190565b60006020828403121561522157600080fd5b81516134e381614cb2565b60006020828403121561523e57600080fd5b5051919050565b60005b83811015615260578181015183820152602001615248565b83811115611c545750506000910152565b60008251615283818460208701615245565b9190910192915050565b60006020828403121561529f57600080fd5b81516134e381614eb6565b600080604083850312156152bd57600080fd5b505080516020909101519092909150565b60208152600082518060208401526152ed816040850160208701615245565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6060815260006153326060830186614d4e565b905083602083015273ffffffffffffffffffffffffffffffffffffffff8316604083015294935050505056fea264697066735822122062234020a79da5894696814a693b51a31d672a6e51f17fa40d3cc3868dc56bea64736f6c634300080d0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000ff5b4bcbf765fe363269114e1c765229a29edefd00000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000260000000000000000000000000d4937682df3c8aef4fe912a96a74121c0829e66400000000000000000000000000000000000000000000000000000000000000020000000000000000000000003432b6a60d23ca0dfca7761b7ab56459d9c964d00000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f50000000000000000000000000000000000000000000000000000000000000002000000000000000000000000b1748c79709f4ba2dd82834b8c82d4a505003f27000000000000000000000000b1748c79709f4ba2dd82834b8c82d4a505003f27000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000a86cc92e3da00000000000000000000000000000000000000000000000000000002b1de5ada0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000278dc748eda1d8efef1adfb518542612b49fcd340000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _owner (address): 0xfF5B4BCbf765FE363269114e1c765229a29eDeFD
Arg [1] : _rewardTokens (address[]): 0x3432B6A60D23Ca0dFCa7761B7ab56459D9C964D0,0x4da27a545c0c5B758a6BA100e3a049001de870f5
Arg [2] : _rewardManagers (address[]): 0xB1748C79709f4Ba2Dd82834B8c82D4a505003f27,0xB1748C79709f4Ba2Dd82834B8c82D4a505003f27
Arg [3] : _rewardRates (uint256[]): 11574074074074,11574074074
Arg [4] : _gaugeControllers (address[]): 0x0000000000000000000000000000000000000000,0x0000000000000000000000000000000000000000
Arg [5] : _rewardDistributors (address[]): 0x278dC748edA1d8eFEf1aDFB518542612b49Fcd34,0x0000000000000000000000000000000000000000
Arg [6] : _stakingToken (address): 0xd4937682df3C8aEF4FE912A96A74121C0829E664
-----Encoded View---------------
22 Constructor Arguments found :
Arg [0] : 000000000000000000000000ff5b4bcbf765fe363269114e1c765229a29edefd
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000140
Arg [3] : 00000000000000000000000000000000000000000000000000000000000001a0
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000200
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000260
Arg [6] : 000000000000000000000000d4937682df3c8aef4fe912a96a74121c0829e664
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [8] : 0000000000000000000000003432b6a60d23ca0dfca7761b7ab56459d9c964d0
Arg [9] : 0000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f5
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [11] : 000000000000000000000000b1748c79709f4ba2dd82834b8c82d4a505003f27
Arg [12] : 000000000000000000000000b1748c79709f4ba2dd82834b8c82d4a505003f27
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [14] : 00000000000000000000000000000000000000000000000000000a86cc92e3da
Arg [15] : 00000000000000000000000000000000000000000000000000000002b1de5ada
Arg [16] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [17] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [18] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [19] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [20] : 000000000000000000000000278dc748eda1d8efef1adfb518542612b49fcd34
Arg [21] : 0000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
105245:523:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58847:529;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;61057:313;;;;;;:::i;:::-;;:::i;:::-;;;1393:25:1;;;1381:2;1366:18;61057:313:0;1247:177:1;57126:109:0;;;:::i;:::-;;;;;;;:::i;46389:141::-;;;;;;:::i;:::-;;:::i;:::-;;97676:190;;;;;;:::i;:::-;;:::i;59440:339::-;;;:::i;94111:133::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;61589:179::-;;;;;;:::i;:::-;;:::i;93864:152::-;;;:::i;56790:298::-;;;;;;:::i;:::-;;:::i;:::-;;;4193:14:1;;4186:22;4168:41;;4156:2;4141:18;56790:298:0;4028:187:1;53929:60:0;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;4396:42:1;4384:55;;;4366:74;;4354:2;4339:18;53929:60:0;4220:226:1;104086:357:0;;;;;;:::i;:::-;;:::i;63137:1752::-;;;;;;:::i;:::-;;:::i;76030:161::-;;;;;;:::i;:::-;;:::i;60493:127::-;;;;;;:::i;:::-;60586:26;;60559:7;60586:26;;;:17;:26;;;;;;;60493:127;52671:48;;52713:6;52671:48;;68933:238;;;;;;:::i;:::-;;:::i;52299:49::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;62289:181;;;;;;:::i;:::-;;:::i;46157:29::-;;;;;;;;;90421:587;90948:4;90421:587;;60207:111;60288:22;;60207:111;;52552:55;;;;;;:::i;:::-;;;;;;;;;;;;;;51578:36;;;;;;57950:681;;;:::i;88869:27::-;;;;;;;;;;;;69640:206;;;;;;:::i;:::-;;:::i;89329:53::-;;;;;;:::i;:::-;;:::i;:::-;;;;6244:25:1;;;6300:2;6285:18;;6278:34;;;;6328:18;;;6321:34;;;;6386:2;6371:18;;6364:34;6429:3;6414:19;;6407:35;6231:3;6216:19;89329:53:0;5985:463:1;46538:271:0;;;:::i;53524:52::-;;;;;;:::i;:::-;;;;;;;;;;;;;;62478:199;;;;;;:::i;:::-;;:::i;76530:1013::-;;;;;;:::i;:::-;;:::i;91115:2589::-;;;;;;:::i;:::-;;:::i;:::-;;;;6655:25:1;;;6711:2;6696:18;;6689:34;;;;6739:18;;;6732:34;6643:2;6628:18;91115:2589:0;6453:319:1;46130:20:0;;;;;;;;;76240:161;;;;;;:::i;:::-;;:::i;54133:26::-;;;;;;;;;61871:224;;;;;;:::i;:::-;;:::i;75885:97::-;;;:::i;51667:55::-;;;;;;65033:278;;;;;;:::i;:::-;;:::i;96068:1479::-;;;;;;:::i;:::-;;:::i;51424:61::-;;;;;;89157:50;;;;;;:::i;:::-;;;;;;;;;;;;;;69460:172;;;;;;:::i;:::-;;:::i;62685:444::-;;;;;;:::i;:::-;;:::i;51270:29::-;;;;;;94320:133;;;;;;:::i;:::-;94417:21;;94390:7;94417:21;;;:12;:21;;;;;:28;;94320:133;75376:311;;;;;;:::i;:::-;;:::i;51350:50::-;;;;;;51073:30;;;;;;61415:166;;;;;;:::i;:::-;;:::i;78586:483::-;;;;;;:::i;:::-;;:::i;66179:419::-;;;;;;:::i;:::-;;:::i;60041:128::-;;;;;;:::i;:::-;60135:26;;60108:7;60135:26;;;:17;:26;;;;;;;60041:128;79144:207;;;;;;:::i;:::-;;:::i;59877:113::-;59959:23;;59877:113;;75780:97;;;:::i;100137:259::-;;;;;;:::i;:::-;;:::i;65479:610::-;;;;;;:::i;:::-;;:::i;104479:298::-;;;;;;:::i;:::-;;:::i;51236:27::-;;;;;;51805:51;;;;;;51881:59;;;;;;57428:452;;;;;;:::i;:::-;;:::i;74055:761::-;;;;;;:::i;:::-;;:::i;77551:958::-;;;;;;:::i;:::-;;:::i;74824:363::-;;;:::i;58847:529::-;58901:27;58941;58971:17;:15;:17::i;:::-;59026:12;:19;58941:47;;-1:-1:-1;59012:34:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;59012:34:0;-1:-1:-1;59063:26:0;;;59092:1;59063:26;;;:17;:26;;;;;;58999:47;;-1:-1:-1;59063:30:0;59059:310;;59114:9;59109:249;59133:12;:19;59129:23;;59109:249;;;59323:16;;;;;;;:7;:16;;;;;;;;:19;;;;;;;;;59242:32;;;:23;:32;;;;;:35;;;;;;;;;59226:13;;59282:4;;59242:35;59226:10;;59340:1;;59226:13;;;;;;:::i;:::-;;;;;;;:51;;;;:::i;:::-;59196:26;;;;;;;:17;:26;;;;;;:82;;;;:::i;:::-;59195:91;;;;:::i;:::-;59194:148;;;;:::i;:::-;59178:10;59189:1;59178:13;;;;;;;;:::i;:::-;;;;;;;;;;:164;59154:3;;;;:::i;:::-;;;;59109:249;;;;59059:310;58930:446;58847:529;;;:::o;61057:313::-;61166:19;;61307:28;;61116:7;;61143:218;;61260:42;51201:4;61166:19;61260:42;:::i;:::-;61252:51;;:4;:51;:::i;:::-;61251:84;;;;:::i;:::-;61200:150;;51201:4;61200:150;:::i;:::-;61143:8;:218::i;:::-;61136:225;61057:313;-1:-1:-1;;61057:313:0:o;57126:109::-;57179:16;57215:12;57208:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57126:109;:::o;46389:141::-;46869:5;;;;46855:10;:19;46847:79;;;;;;;11884:2:1;46847:79:0;;;11866:21:1;11923:2;11903:18;;;11896:30;11962:34;11942:18;;;11935:62;12033:17;12013:18;;;12006:45;12068:19;;46847:79:0;;;;;;;;;46461:14:::1;:23:::0;;;::::1;;::::0;::::1;::::0;;::::1;::::0;;;46500:22:::1;::::0;4366:74:1;;;46500:22:0::1;::::0;4354:2:1;4339:18;46500:22:0::1;;;;;;;46389:141:::0;:::o;97676:190::-;97761:7;45064:1;45670:7;;:19;45662:63;;;;;;;12300:2:1;45662:63:0;;;12282:21:1;12339:2;12319:18;;;12312:30;12378:33;12358:18;;;12351:61;12429:18;;45662:63:0;12098:355:1;45662:63:0;45064:1;45803:18;;97788:70:::1;97801:10;::::0;97825:9;97836:4;97842:15:::1;97788:12;:70::i;:::-;45020:1:::0;45982:7;:22;97781:77;97676:190;-1:-1:-1;;;97676:190:0:o;59440:339::-;59590:17;:24;59495:41;;59576:39;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;59576:39:0;;59549:66;;59633:9;59628:144;59652:17;:24;59648:28;;59628:144;;;52713:6;59728:14;59740:1;59728:11;:14::i;:::-;:32;;;;:::i;:::-;59698:24;59723:1;59698:27;;;;;;;;:::i;:::-;;;;;;;;;;:62;59678:3;;;;:::i;:::-;;;;59628:144;;;;59440:339;:::o;94111:133::-;94215:21;;;;;;;:12;:21;;;;;;;;94208:28;;;;;;;;;;;;;;;;;94175:20;;94208:28;;94215:21;;94208:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;94111:133;;;:::o;61589:179::-;61704:32;;;61658:7;61704:32;;;:17;:32;;;;;;61686:15;;51201:4;;61686:50;;;:::i;:::-;61685:75;;;;:::i;93864:152::-;93907:7;93947:12;;;;;;;;;;;:17;;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;93934:74;;;;;50989:42;93934:74;;;4366::1;93934:60:0;;;;;;;;4339:18:1;;93934:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;93927:81;;93864:152;:::o;56790:298::-;56886:4;56921:5;;;;;;56906:20;;;;56902:136;;-1:-1:-1;56935:4:0;56928:11;;56902:136;56977:48;:33;;;;;;;:14;:33;;;;;;:48;;;:33;;:48;56973:65;;-1:-1:-1;57034:4:0;57027:11;;56973:65;-1:-1:-1;57074:5:0;56790:298;;;;:::o;104086:357::-;55030:12;;;;;;;;:20;;:12;:20;55022:49;;;;;;;13105:2:1;55022:49:0;;;13087:21:1;13144:2;13124:18;;;13117:30;13183:18;13163;;;13156:46;13219:18;;55022:49:0;12903:340:1;55022:49:0;104239:40:::1;::::0;::::1;;::::0;;;:24:::1;:40;::::0;;;;;;;104280:10:::1;104239:52:::0;;;;;;;;::::1;;:83:::0;::::1;;;-1:-1:-1::0;104311:10:0::1;104295:27;::::0;;;:15:::1;:27;::::0;;;;;::::1;;104239:83;104231:122;;;::::0;::::1;::::0;;13450:2:1;104231:122:0::1;::::0;::::1;13432:21:1::0;13489:2;13469:18;;;13462:30;13528:28;13508:18;;;13501:56;13574:18;;104231:122:0::1;13248:350:1::0;104231:122:0::1;104364:71;104377:14;104393:10;104405:6;104413:4;104419:15;104364:12;:71::i;:::-;;104086:357:::0;;;;:::o;63137:1752::-;63200:24;;;63361:20;63373:7;63361:11;:20::i;:::-;63341:40;-1:-1:-1;63412:23:0;;;;63411:81;;63466:5;;:26;;;;;:5;4384:55:1;;;63466:26:0;;;4366:74:1;63466:5:0;;;;:15;;4339:18:1;;63466:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;63411:81;;;63439:5;;:24;;;;;:5;4384:55:1;;;63439:24:0;;;4366:74:1;63439:5:0;;;;:15;;4339:18:1;;63439:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;63392:100;;63598:19;51201:4;63722:5;;;;;;;;;;;:17;;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:42;;;;:::i;:::-;63663:24;;63640:20;;63621:39;;:16;:39;:::i;:::-;:66;;;;:::i;:::-;63620:145;;;;:::i;:::-;63598:167;-1:-1:-1;63874:19:0;;64089:23;;;;64088:94;;64147:35;64172:9;64147:24;:35::i;:::-;64088:94;;;64116:28;64136:7;64116:19;:28::i;:::-;64059:123;-1:-1:-1;64203:30:0;;64199:323;;64254:27;64328:26;64285:39;51201:4;64285:16;:39;:::i;:::-;64284:70;;;;:::i;:::-;64254:100;;51201:4;64428:20;;64406:19;:42;;;;:::i;:::-;64405:67;;;;:::i;:::-;64391:81;;64234:254;64199:323;;;64521:1;64507:15;;64199:323;63904:699;64690:11;64676;:25;:53;;64718:11;64676:53;;;64704:11;64676:53;64656:74;;64820:20;;64801:16;:39;64797:84;;;64861:20;;64842:39;;64797:84;63226:1663;;;;63137:1752;;;:::o;76030:161::-;54672:5;;;;54658:10;:19;;:79;;-1:-1:-1;54695:42:0;54681:10;:56;54658:79;54650:113;;;;;;;13805:2:1;54650:113:0;;;13787:21:1;13844:2;13824:18;;;13817:30;13883:23;13863:18;;;13856:51;13924:18;;54650:113:0;13603:345:1;54650:113:0;76150:33:::1;;;::::0;;;:15:::1;:33;::::0;;;;;;76113:70;;::::1;76150:33;::::0;;::::1;76149:34;76113:70;::::0;;76030:161::o;68933:238::-;45064:1;45670:7;;:19;45662:63;;;;;;;12300:2:1;45662:63:0;;;12282:21:1;12339:2;12319:18;;;12312:30;12378:33;12358:18;;;12351:61;12429:18;;45662:63:0;12098:355:1;45662:63:0;45064:1;45803:18;;69030:23:::1;::::0;;;::::1;;;:32;69022:70;;;::::0;::::1;::::0;;14155:2:1;69022:70:0::1;::::0;::::1;14137:21:1::0;14194:2;14174:18;;;14167:30;14233:27;14213:18;;;14206:55;14278:18;;69022:70:0::1;13953:349:1::0;69022:70:0::1;-1:-1:-1::0;45020:1:0;45982:7;:22;68933:238::o;62289:181::-;62356:7;51201:4;62410:28;;62384:23;62399:7;62384:14;:23::i;:::-;:54;;;;:::i;57950:681::-;57998:41;58056:23;;58083:1;58056:28;:59;;;-1:-1:-1;58088:22:0;;:27;58056:59;58052:572;;;58139:21;58132:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57950:681;:::o;58052:572::-;58243:12;:19;58229:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;58229:34:0;;58202:61;;58283:9;58278:289;58302:21;:28;58298:32;;58278:289;;;58510:22;;58485:14;58497:1;58485:11;:14::i;:::-;58467;;58438:26;:24;:26::i;:::-;:43;;;;:::i;:::-;58437:62;;;;:::i;:::-;:69;;58502:4;58437:69;:::i;:::-;58436:96;;;;:::i;:::-;58386:21;58408:1;58386:24;;;;;;;;:::i;:::-;;;;;;;;;:165;;;;:::i;:::-;58356:24;58381:1;58356:27;;;;;;;;:::i;:::-;;;;;;;;;;:195;58332:3;;;;:::i;:::-;;;;58278:289;;69640:206;69742:16;45064:1;45670:7;;:19;45662:63;;;;;;;12300:2:1;45662:63:0;;;12282:21:1;12339:2;12319:18;;;12312:30;12378:33;12358:18;;;12351:61;12429:18;;45662:63:0;12098:355:1;45662:63:0;45064:1;45803:18;;69778:60:::1;69789:10;69801:19:::0;69822:15;69778:10:::1;:60::i;89329:53::-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;89329:53:0;;-1:-1:-1;89329:53:0;;;:::o;46538:271::-;46607:14;;;;46593:10;:28;46585:94;;;;;;;14509:2:1;46585:94:0;;;14491:21:1;14548:2;14528:18;;;14521:30;14587:34;14567:18;;;14560:62;14658:23;14638:18;;;14631:51;14699:19;;46585:94:0;14307:417:1;46585:94:0;46708:5;;;46715:14;46695:35;;;46708:5;;;;14964:34:1;;46715:14:0;;;;15029:2:1;15014:18;;15007:43;46695:35:0;;14876:18:1;46695:35:0;;;;;;;46749:14;;;;46741:22;;;;;;46749:14;;;46741:22;;;;46774:27;;;46538:271::o;62478:199::-;62556:7;51201:4;62617:28;;62584:30;62600:13;62584:15;:30::i;76530:1013::-;54875:5;;76616:12;;54875:5;;54861:10;:19;;:74;;;54884:51;54902:10;54914:20;54884:17;:51::i;:::-;54853:107;;;;;;;15263:2:1;54853:107:0;;;15245:21:1;15302:2;15282:18;;;15275:30;15341:22;15321:18;;;15314:50;15381:18;;54853:107:0;15061:344:1;54853:107:0;76698:18:::1;76740:9:::0;76735:192:::1;76759:12;:19:::0;76755:23;::::1;76735:192;;;76823:12;76804:31;;:12;76817:1;76804:15;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;::::1;;:31:::0;76800:116:::1;;76872:4;76856:20;;76895:5;;76800:116;76780:3:::0;::::1;::::0;::::1;:::i;:::-;;;;76735:192;;;;77153:13;:59;;;;-1:-1:-1::0;77170:42:0::1;:28:::0;;::::1;;::::0;;;:14:::1;:28;::::0;;;;;::::1;77202:10;77170:42;77153:59;77152:123;;;;77236:13;77235:14;:39;;;;-1:-1:-1::0;77268:5:0::1;::::0;::::1;;77254:10;:19;77235:39;77130:406;;;77306:66;77334:12;77348:10;77360:11;77306:27;:66::i;:::-;77387:7;76530:1013:::0;;;:::o;77130:406::-:1;77488:36;::::0;::::1;::::0;;15612:2:1;77488:36:0::1;::::0;::::1;15594:21:1::0;15651:2;15631:18;;;15624:30;15690:28;15670:18;;;15663:56;15736:18;;77488:36:0::1;15410:350:1::0;54971:1:0::1;76530:1013:::0;;;:::o;91115:2589::-;91418:26;;;91216:27;91418:26;;;:17;:26;;;;;;;91216:27;91605:24;91436:7;91605:15;:24::i;:::-;91690:26;;;91642:33;91690:26;;;:17;:26;;;;;;91582:47;;-1:-1:-1;91642:33:0;91690:31;:66;;;;-1:-1:-1;91725:26:0;;;;;;;:17;:26;;;;;;:31;91690:66;91686:386;;;-1:-1:-1;91910:20:0;91686:386;;;92024:31;;;;;;;:22;:31;;;;;;92059:1;;92001:54;;:20;:54;:::i;:::-;92000:60;;;;:::i;:::-;91972:88;;91686:386;92207:1;92185:23;;92224:9;92219:1478;92243:21;;;;;;;:12;:21;;;;;:28;92239:32;;92219:1478;;;92324:21;;;92293:28;92324:21;;;:12;:21;;;;;:24;;92346:1;;92324:24;;;;;;:::i;:::-;;;;;;;;;;;92293:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92363:23;92389:9;:25;;;92363:51;;92504:15;92474:9;:26;;;:45;92470:947;;92707:26;;;;92676:28;;;;;;;:19;:28;;;;;;:57;92672:730;;;92815:28;;;92757:26;92815:28;;;:19;:28;;;;;;92786:26;;;;:57;;92815:28;92786:57;:::i;:::-;92757:86;;92866:25;92912:9;:26;;;92894:15;:44;;;;:::i;:::-;92866:72;-1:-1:-1;93028:17:0;93090:40;92866:72;51201:4;93090:40;:::i;:::-;93049:36;93067:18;93049:15;:36;:::i;:::-;93048:83;;;;:::i;:::-;93028:103;-1:-1:-1;93185:38:0;93206:17;93185:18;:38;:::i;:::-;93172:52;;:9;:52;:::i;:::-;93154:70;;92734:510;;;92672:730;;;-1:-1:-1;51201:4:0;92672:730;93453:19;;;;93433:17;51201:4;93535:43;93553:25;93535:15;:43;:::i;:::-;93522:57;;:9;:57;:::i;:::-;93521:82;;;;:::i;:::-;93487:116;-1:-1:-1;93640:45:0;93487:116;93640:19;:45;:::i;:::-;93618:67;;92278:1419;;;;92273:3;;;;;:::i;:::-;;;;92219:1478;;;;91345:2359;91115:2589;;;;;:::o;76240:161::-;54672:5;;;;54658:10;:19;;:79;;-1:-1:-1;54695:42:0;54681:10;:56;54658:79;54650:113;;;;;;;13805:2:1;54650:113:0;;;13787:21:1;13844:2;13824:18;;;13817:30;13883:23;13863:18;;;13856:51;13924:18;;54650:113:0;13603:345:1;54650:113:0;76361:32:::1;;;::::0;;;:19:::1;:32;::::0;;;;;;76325:68;;::::1;76361:32;::::0;;::::1;76360:33;76325:68;::::0;;76240:161::o;61871:224::-;61937:7;62071:15;;62040:28;;:46;;;;:::i;:::-;61965:5;;:24;;;;;:5;4384:55:1;;;61965:24:0;;;4366:74:1;51201:4:0;;;;61965:5;;;:15;;4339:18:1;;61965:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:47;;;;:::i;75885:97::-;54672:5;;;;54658:10;:19;;:79;;-1:-1:-1;54695:42:0;54681:10;:56;54658:79;54650:113;;;;;;;13805:2:1;54650:113:0;;;13787:21:1;13844:2;13824:18;;;13817:30;13883:23;13863:18;;;13856:51;13924:18;;54650:113:0;13603:345:1;54650:113:0;75962:12:::1;::::0;;75946:28;;::::1;75962:12;::::0;;;::::1;;;75961:13;75946:28:::0;;::::1;;::::0;;75885:97::o;65033:278::-;65117:33;;;;;;;:15;:33;;;;;;;;65109:70;;;;;;;15967:2:1;65109:70:0;;;15949:21:1;16006:2;15986:18;;;15979:30;16045:26;16025:18;;;16018:54;16089:18;;65109:70:0;15765:348:1;65109:70:0;65273:10;65248:36;;;;:24;:36;;;;;;;;;:54;;;;;;;;;;;;;;;65247:55;65190:112;;;;;;;65033:278::o;96068:1479::-;96149:10;96161:4;55174:42;55198:7;55207:8;55174:23;:42::i;:::-;96226:28:::1;96256:21:::0;96281:29:::1;96291:10;96303:6;96281:9;:29::i;:::-;96225:85;;;;96397:53;96413:10;96425:9;96436:13;96397:15;:53::i;:::-;-1:-1:-1::0;96381:69:0;-1:-1:-1;96534:1:0::1;96522:13:::0;;;96518:26:::1;;96537:7;;;;96518:26;96593:15;96633:8;96611:9;:19;;;:30;;;;:::i;:::-;96593:48:::0;-1:-1:-1;96812:12:0::1;::::0;96772:91:::1;::::0;96812:12;;::::1;;;96827:10;96847:4;96854:8:::0;96772:31:::1;:91::i;:::-;96947:186;::::0;;::::1;::::0;::::1;::::0;;;;;::::1;96994:25:::0;;::::1;::::0;96947:186;;::::1;::::0;;;;;;;;97056:26;;::::1;::::0;96947:186;;;;;97097:25;;::::1;::::0;96947:186;;;;96918:10:::1;-1:-1:-1::0;96905:24:0;;;:12:::1;:24:::0;;;;;;;:39;;96930:13;;96905:39;::::1;;;;;:::i;:::-;;;;;;;;;;;:228;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97204:8;97177:23;;:35;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;97241:10:0::1;97223:29;::::0;;;:17:::1;:29;::::0;;;;:41;;97256:8;;97223:29;:41:::1;::::0;97256:8;;97223:41:::1;:::i;:::-;::::0;;;-1:-1:-1;97290:17:0::1;::::0;-1:-1:-1;97310:23:0::1;97322:10;97310:11;:23::i;:::-;97290:43:::0;-1:-1:-1;97352:23:0::1;::::0;::::1;::::0;97348:69:::1;;97377:28;::::0;::::1;;::::0;;;:17:::1;:28:::0;;;;;:40;;97409:8;;97377:28;:40:::1;::::0;97409:8;;97377:40:::1;:::i;:::-;::::0;;;-1:-1:-1;;97348:69:0::1;97275:154;97497:42;97521:10;97533:5;97497:23;:42::i;:::-;96174:1373;;;96068:1479:::0;;;;:::o;69460:172::-;69539:16;45064:1;45670:7;;:19;45662:63;;;;;;;12300:2:1;45662:63:0;;;12282:21:1;12339:2;12319:18;;;12312:30;12378:33;12358:18;;;12351:61;12429:18;;45662:63:0;12098:355:1;45662:63:0;45064:1;45803:18;;69575:49:::1;69586:10;69598:19:::0;69619:4:::1;69575:10;:49::i;:::-;45020:1:::0;45982:7;:22;69568:56;69460:172;-1:-1:-1;;69460:172:0:o;62685:444::-;62764:25;;;62741:7;62764:25;;;:19;:25;;;;;;;;62760:362;;;-1:-1:-1;62967:4:0;62685:444::o;62760:362::-;-1:-1:-1;63079:31:0;;;;;;;;:25;:31;;;;;;;;62685:444::o;75376:311::-;54672:5;;;;54658:10;:19;;:79;;-1:-1:-1;54695:42:0;54681:10;:56;54658:79;54650:113;;;;;;;13805:2:1;54650:113:0;;;13787:21:1;13844:2;13824:18;;;13817:30;13883:23;13863:18;;;13856:51;13924:18;;54650:113:0;13603:345:1;54650:113:0;75539:13:::1;:30:::0;;75629:50;::::1;;::::0;::::1;::::0;75580:38;::::1;;::::0;::::1;::::0;75539:30;::::1;;::::0;::::1;75580:38:::0;;;;;;;;;;;;;;;::::1;75629:50:::0;;;::::1;;::::0;;75376:311::o;61415:166::-;61523:26;;;61477:7;61523:26;;;:17;:26;;;;;;61505:15;;51201:4;;61505:44;;;:::i;78586:483::-;54875:5;;78752:20;;54875:5;;54861:10;:19;;:74;;;54884:51;54902:10;54914:20;54884:17;:51::i;:::-;54853:107;;;;;;;15263:2:1;54853:107:0;;;15245:21:1;15302:2;15282:18;;;15275:30;15341:22;15321:18;;;15314:50;15381:18;;54853:107:0;15061:344:1;54853:107:0;78803:42:::1;::::0;::::1;;::::0;;;:20:::1;:42;::::0;;;;;78785:17:::1;:61:::0;;78849:9;;78803:42;78785:61;::::1;;;;;:::i;:::-;;;;;;;;:73;;;;78932:25;78869:16;78886:20;:42;78907:20;78886:42;;;;;;;;;;;;;;;;78869:60;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;;;::::1;:88:::0;;;::::1;;::::0;;::::1;;::::0;;78987:42;;::::1;::::0;;:20:::1;:42:::0;;;;;;;78968:18:::1;:62:::0;;79033:28;;78987:42;78968:62;::::1;;;;;:::i;:::-;;;;;;;;;:93;;;;;;;;;;;;;;;;;;78586:483:::0;;;;;:::o;66179:419::-;66259:34;;;;;;;:19;:34;;;;;;;;66251:60;;;;;;;16665:2:1;66251:60:0;;;16647:21:1;16704:2;16684:18;;;16677:30;16743:15;16723:18;;;16716:43;16776:18;;66251:60:0;16463:337:1;66251:60:0;66330:36;;;;;;;:21;:36;;;;;;;;66367:10;66330:48;;;;;;;;;;66322:90;;;;;;;17007:2:1;66322:90:0;;;16989:21:1;17046:2;17026:18;;;17019:30;17085:31;17065:18;;;17058:59;17134:18;;66322:90:0;16805:353:1;66322:90:0;66449:10;66423:37;;;;:25;:37;;;;;;;;:53;;;;:37;:53;;;;;;;;66561:17;:29;;;;;;66525:32;;;;;;;;:65;;66561:29;;66525:32;;:65;;66561:29;;66525:65;:::i;:::-;;;;-1:-1:-1;;;66179:419:0:o;79144:207::-;54875:5;;79252:20;;54875:5;;54861:10;:19;;:74;;;54884:51;54902:10;54914:20;54884:17;:51::i;:::-;54853:107;;;;;;;15263:2:1;54853:107:0;;;15245:21:1;15302:2;15282:18;;;15275:30;15341:22;15321:18;;;15314:50;15381:18;;54853:107:0;15061:344:1;54853:107:0;-1:-1:-1;79285:36:0::1;::::0;;::::1;;::::0;;;:14:::1;:36;::::0;;;;:58;;;::::1;::::0;;;::::1;;::::0;;79144:207::o;75780:97::-;54672:5;;;;54658:10;:19;;:79;;-1:-1:-1;54695:42:0;54681:10;:56;54658:79;54650:113;;;;;;;13805:2:1;54650:113:0;;;13787:21:1;13844:2;13824:18;;;13817:30;13883:23;13863:18;;;13856:51;13924:18;;54650:113:0;13603:345:1;54650:113:0;75855:14:::1;::::0;;75837:32;;::::1;75855:14;::::0;;::::1;75854:15;75837:32;::::0;;75780:97::o;100137:259::-;100237:7;45064:1;45670:7;;:19;45662:63;;;;;;;12300:2:1;45662:63:0;;;12282:21:1;12339:2;12319:18;;;12312:30;12378:33;12358:18;;;12351:61;12429:18;;45662:63:0;12098:355:1;45662:63:0;45064:1;45803:18;;100265:17:::1;::::0;;;::::1;;;:26;100257:57;;;::::0;::::1;::::0;;17365:2:1;100257:57:0::1;::::0;::::1;17347:21:1::0;17404:2;17384:18;;;17377:30;17443:20;17423:18;;;17416:48;17481:18;;100257:57:0::1;17163:342:1::0;100257:57:0::1;100332:56;100348:10;100360:19;100381:6;100332:15;:56::i;65479:610::-:0;65578:10;65558:31;;;;:19;:31;;;;;;;;65550:57;;;;;;;16665:2:1;65550:57:0;;;16647:21:1;16704:2;16684:18;;;16677:30;16743:15;16723:18;;;16716:43;16776:18;;65550:57:0;16463:337:1;65550:57:0;65693:10;65671:33;;;;:21;:33;;;;;;;;;:49;;;;;;;;;;;;;;;;65670:50;65618:102;;;;;;;65823:25;:41;;;;;;;;:55;65819:263;;65894:41;;;65946:1;65894:41;;;:25;:41;;;;;;;;:54;;;;;;66037:17;:33;;;;;;66022:10;66004:29;;;;;;;:66;;66037:33;;66004:29;;:66;;66037:33;;66004:66;:::i;65819:263::-;65479:610;:::o;104479:298::-;55030:12;;;;;;;;:20;;:12;:20;55022:49;;;;;;;13105:2:1;55022:49:0;;;13087:21:1;13144:2;13124:18;;;13117:30;13183:18;13163;;;13156:46;13219:18;;55022:49:0;12903:340:1;55022:49:0;104593:40:::1;::::0;::::1;;::::0;;;:24:::1;:40;::::0;;;;;;;104634:10:::1;104593:52:::0;;;;;;;;::::1;;:83:::0;::::1;;;-1:-1:-1::0;104665:10:0::1;104649:27;::::0;;;:15:::1;:27;::::0;;;;;::::1;;104593:83;104585:122;;;::::0;::::1;::::0;;13450:2:1;104585:122:0::1;::::0;::::1;13432:21:1::0;13489:2;13469:18;;;13462:30;13528:28;13508:18;;;13501:56;13574:18;;104585:122:0::1;13248:350:1::0;104585:122:0::1;104718:51;104734:14;104750:10;104762:6;104718:15;:51::i;57428:452::-:0;57489:16;57518:32;57553:16;57570:9;57553:27;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;57595:38:0;;57591:282;;57776:4;57734:27;57762:9;57734:38;;;;;;;;:::i;:::-;;;;;;;;;57683:24;57662:67;;;:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:110;;;;:::i;:::-;57661:119;;;;:::i;:::-;57650:130;;57591:282;;;57833:17;57851:9;57833:28;;;;;;;;:::i;:::-;;;;;;;;;57822:39;;57507:373;57428:452;;;:::o;74055:761::-;74172:9;74167:642;74191:16;:23;74187:27;;74167:642;;;74236:32;74271:16;74288:1;74271:19;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;74309:38:0;;74305:493;;74372:12;:61;;;;74407:22;74430:1;74407:25;;;;;;;;:::i;:::-;;;;;;;;;74389:15;:43;74372:61;74368:415;;;74547:106;;;;;74630:4;74547:106;;;17684:74:1;74637:15:0;17774:18:1;;;17767:34;74547:74:0;;;;;;17657:18:1;;74547:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74514:27;74542:1;74514:30;;;;;;;;:::i;:::-;;;;;;;;:139;;;;74725:24;74704:57;;;:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74676:22;74699:1;74676:25;;;;;;;;:::i;:::-;;;;;;;;;;:87;74368:415;-1:-1:-1;74216:3:0;;;;:::i;:::-;;;;74167:642;;;;74055:761;:::o;77551:958::-;54672:5;;;;54658:10;:19;;:79;;-1:-1:-1;54695:42:0;54681:10;:56;54658:79;54650:113;;;;;;;13805:2:1;54650:113:0;;;13787:21:1;13844:2;13824:18;;;13817:30;13883:23;13863:18;;;13856:51;13924:18;;54650:113:0;13603:345:1;54650:113:0;77960:13;;51201:4:::1;-1:-1:-1::0;77960:37:0::1;77952:69;;;::::0;::::1;::::0;;18014:2:1;77952:69:0::1;::::0;::::1;17996:21:1::0;18053:2;18033:18;;;18026:30;18092:21;18072:18;;;18065:49;18131:18;;77952:69:0::1;17812:343:1::0;77952:69:0::1;78145:13:::0;;::::1;::::0;78162:1:::1;-1:-1:-1::0;78145:18:0;::::1;::::0;78144:44:::1;;-1:-1:-1::0;78169:13:0;;::::1;::::0;78186:1:::1;-1:-1:-1::0;78169:18:0::1;78144:44;78136:69;;;::::0;::::1;::::0;;18703:2:1;78136:69:0::1;::::0;::::1;18685:21:1::0;18742:2;18722:18;;;18715:30;18781:14;18761:18;;;18754:42;18813:18;;78136:69:0::1;18501:336:1::0;78136:69:0::1;78240:13:::0;;78218:19:::1;:35:::0;78240:13:::1;78287::::0;::::1;::::0;78264:20:::1;:36:::0;78342:13;;::::1;::::0;78311:28:::1;:44:::0;78393:13;;::::1;::::0;78366:24:::1;:40:::0;78448:13;;::::1;::::0;78417:28:::1;:44:::0;78488:13;::::1;::::0;78472::::1;:29:::0;77551:958::o;74824:363::-;74907:25;74926:5;74907:18;:25::i;:::-;90948:4;74984:15;:34;75054:12;;75035:15;:31;75031:149;;75083:14;:12;:14::i;:::-;74824:363::o;75031:149::-;75139:29;:27;:29::i;522:106::-;580:7;611:1;607;:5;:13;;619:1;607:13;;;615:1;607:13;600:20;522:106;-1:-1:-1;;;522:106:0:o;98062:1901::-;98305:7;98274:14;98290:4;55174:42;55198:7;55207:8;55174:23;:42::i;:::-;98333:13:::1;::::0;;;::::1;;;:22;::::0;:61:::1;;-1:-1:-1::0;98375:10:0::1;98359:27;::::0;;;:15:::1;:27;::::0;;;;;::::1;;:35;;:27:::0;:35:::1;98333:61;98325:104;;;::::0;::::1;::::0;;19044:2:1;98325:104:0::1;::::0;::::1;19026:21:1::0;19083:2;19063:18;;;19056:30;19122:32;19102:18;;;19095:60;19172:18;;98325:104:0::1;18842:354:1::0;98325:104:0::1;98456:13;;98448:4;:21;;98440:60;;;::::0;::::1;::::0;;19403:2:1;98440:60:0::1;::::0;::::1;19385:21:1::0;19442:2;19422:18;;;19415:30;19481:28;19461:18;;;19454:56;19527:18;;98440:60:0::1;19201:350:1::0;98440:60:0::1;98527:28;;98519:4;:36;;98511:75;;;::::0;::::1;::::0;;19758:2:1;98511:75:0::1;::::0;::::1;19740:21:1::0;19797:2;19777:18;;;19770:30;19836:29;19816:18;;;19809:57;19883:18;;98511:75:0::1;19556:351:1::0;98511:75:0::1;98709:12;::::0;98669:96:::1;::::0;98709:12;;::::1;;;98724:14:::0;98748:4:::1;98755:9:::0;98669:31:::1;:96::i;:::-;98825:23;98851:20;98866:4;98851:14;:20::i;:::-;98970:33;::::0;::::1;98882:14;98970:33:::0;;;:17:::1;:33;::::0;;;;;;;;98909:95;;20158:66:1;20145:2;20141:15;;;20137:88;98909:95:0;;::::1;20125:101:1::0;;;;20242:12;;;20235:28;;;20279:12;;;20272:28;;;20316:12;;;20309:28;98825:46:0;;-1:-1:-1;98882:14:0;20353:13:1;;98909:95:0::1;::::0;;;;;::::1;::::0;;;;;;98899:106;;98909:95:::1;98899:106:::0;;::::1;::::0;99062:28:::1;::::0;::::1;;::::0;;;:12:::1;:28:::0;;;;;99096:164:::1;::::0;::::1;::::0;;;;;;;::::1;::::0;;;;;;;;;98899:106;;-1:-1:-1;99062:28:0;99096:164;;;99197:22:::1;99215:4:::0;99143:15;99197:22:::1;:::i;:::-;99096:164:::0;;::::1;::::0;;::::1;::::0;;;99062:199;;::::1;::::0;;::::1;::::0;;-1:-1:-1;99062: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;99392:12:::1;:10;:12::i;:::-;99366:23;::::0;;;:15:::1;:23;::::0;;;;:38;;;;99448:23:::1;:36:::0;;99475:9;;99366:23;99448:36:::1;::::0;99475:9;;99448:36:::1;:::i;:::-;::::0;;;-1:-1:-1;;99495:33:0::1;::::0;::::1;;::::0;;;:17:::1;:33;::::0;;;;:46;;99532:9;;99495:33;:46:::1;::::0;99532:9;;99495:46:::1;:::i;:::-;::::0;;;-1:-1:-1;99567:17:0::1;::::0;-1:-1:-1;99587:27:0::1;99599:14:::0;99587:11:::1;:27::i;:::-;99567:47:::0;-1:-1:-1;99633:23:0::1;::::0;::::1;::::0;99629:70:::1;;99658:28;::::0;::::1;;::::0;;;:17:::1;:28:::0;;;;;:41;;99690:9;;99658:28;:41:::1;::::0;99690:9;;99658:41:::1;:::i;:::-;::::0;;;-1:-1:-1;;99629:70:0::1;99552:159;99797:46;99821:14;99837:5;99797:23;:46::i;:::-;99861:68;::::0;;20608:25:1;;;20664:2;20649:18;;20642:34;;;20692:18;;;20685:34;;;99861:68:0::1;20755:55:1::0;;;20750:2;20735:18;;20728:83;99861:68:0;::::1;::::0;::::1;::::0;20595:3:1;20580:19;99861:68:0::1;;;;;;;99949:6:::0;98062:1901;-1:-1:-1;;;;;;;;;98062:1901:0:o;57287:133::-;57346:7;57373:39;57382:15;57399:12;;57373:8;:39::i;69942:1006::-;70087:31;70062:8;70072:4;55174:42;55198:7;55207:8;55174:23;:42::i;:::-;70193:23:::1;::::0;;;::::1;;;:32;70185:70;;;::::0;::::1;::::0;;14155:2:1;70185:70:0::1;::::0;::::1;14137:21:1::0;14194:2;14174:18;;;14167:30;14233:27;14213:18;;;14206:55;14278:18;;70185:70:0::1;13953:349:1::0;70185:70:0::1;70367:12;:19:::0;70353:34:::1;::::0;::::1;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;70353:34:0::1;;70336:51;;70405:9;70400:282;70424:12;:19:::0;70420:23;::::1;70400:282;;;70485:17;::::0;::::1;;::::0;;;:7:::1;:17;::::0;;;;;;;:20;;;;;;;;;70465:17;;:14;;70503:1;;70465:17;::::1;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;:40;;;;70520:17:::1;::::0;::::1;70543:1;70520:17:::0;;;:7:::1;:17:::0;;;;;;:20;;;;;;;;;:24;;;70563:17;;:14;;70538:1;;70563:17;::::1;;;;;:::i;:::-;;;;;;;:21;70559:111;;;70586:84;70614:12;70627:1;70614:15;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;70631:19;70652:14;70667:1;70652:17;;;;;;;;:::i;:::-;;;;;;;70586:27;:84::i;:::-;70445:3:::0;::::1;::::0;::::1;:::i;:::-;;;;70400:282;;;;-1:-1:-1::0;;70893:29:0::1;::::0;;::::1;;::::0;;;:19:::1;:29;::::0;;;;70925:15:::1;70893:47:::0;;-1:-1:-1;69942:1006:0;;;-1:-1:-1;69942:1006:0:o;38700:361::-;38895:45;;;38884:10;17702:55:1;;;38895:45:0;;;17684:74:1;17774:18;;;;17767:34;;;38895:45:0;;;;;;;;;;17657:18:1;;;;38895:45:0;;;;;;;;;;;;;38884:57;;-1:-1:-1;;;;38884:10:0;;;;:57;;38895:45;38884:57;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38848:93;;;;38960:7;:57;;;;-1:-1:-1;38972:11:0;;:16;;:44;;;39003:4;38992:24;;;;;;;;;;;;:::i;:::-;38952:101;;;;;;;21816:2:1;38952:101:0;;;21798:21:1;21855:2;21835:18;;;21828:30;21894:33;21874:18;;;21867:61;21945:18;;38952:101:0;21614:355:1;66764:1525:0;66954:8;66950:46;;;66978:6;:4;:6::i;:::-;67020:21;;;;67016:1266;;67234:27;67280:28;67327:27;67372:30;67394:7;67372:21;:30::i;:::-;67212:190;;;;;;67464:20;67476:7;67464:11;:20::i;:::-;67560:31;;;;;;;:22;:31;;;;;:54;;;67701:42;;;67697:572;;67764:19;67786:41;67808:19;67786;:41;:::i;:::-;67764:63;;67896:11;67871:22;;:36;;;;:::i;:::-;67846:22;:61;67955:33;67977:11;67955:19;:33;:::i;:::-;67926:26;;;;;;;:17;:26;;;;;:62;-1:-1:-1;67697:572:0;;;68029:19;68051:41;68073:19;68051;:41;:::i;:::-;68029:63;;68161:11;68136:22;;:36;;;;:::i;:::-;68111:22;:61;68220:33;68242:11;68220:19;:33;:::i;:::-;68191:26;;;;;;;:17;:26;;;;;:62;-1:-1:-1;67043:1239:0;;;66764:1525;;:::o;95414:508::-;95496:31;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;95496:31:0;95529:15;;95557:280;95581:28;;;;;;;:12;:28;;;;;:35;95577:39;;95557:280;;;95652:28;;;;;;;:12;:28;;;;;:31;;95681:1;;95652:31;;;;;;:::i;:::-;;;;;;;;;;;:38;;;95642:6;:48;95638:188;;95725:28;;;;;;;:12;:28;;;;;:31;;95754:1;;95725:31;;;;;;:::i;:::-;;;;;;;;;;;95710:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;95785:1;95775:11;;95805:5;;95638:188;95618:3;;;;:::i;:::-;;;;95557:280;;;-1:-1:-1;95855:19:0;;:29;;95847:57;;;;;;;22176:2:1;95847:57:0;;;22158:21:1;22215:2;22195:18;;;22188:30;22254:17;22234:18;;;22227:45;22289:18;;95847:57:0;21974:339:1;95847:57:0;95414:508;;;;;:::o;102566:1172::-;102722:18;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102722:18:0;102988:16;;102742:7;102972:33;;;:15;:33;;;;;;102742:7;;102956:12;:10;:12::i;:::-;102934:9;:19;;;:34;;;;:::i;:::-;102933:72;;;;:::i;:::-;102915:90;;103016:16;103045:9;:19;;;103035:7;:29;;;;:::i;:::-;103114:28;;;;;;;:12;:28;;;;;:43;;103016:48;;-1:-1:-1;103170:7:0;;103143:13;;103114:43;;;;;;:::i;:::-;;;;;;;;;;;:53;;:63;;;;103257:8;103230:23;;:35;;;;;;;:::i;:::-;;;;-1:-1:-1;;103276:33:0;;;;;;;:17;:33;;;;;:45;;103313:8;;103276:33;:45;;103313:8;;103276:45;:::i;:::-;;;;-1:-1:-1;103347:17:0;;-1:-1:-1;103367:27:0;103379:14;103367:11;:27::i;:::-;103347:47;-1:-1:-1;103413:23:0;;;;103409:69;;103438:28;;;;;;;:17;:28;;;;;:40;;103470:8;;103438:28;:40;;103470:8;;103438:40;:::i;:::-;;;;-1:-1:-1;;103409:69:0;103332:158;103634:12;:10;:12::i;:::-;103614:16;;103598:33;;;;:15;:33;;;;;;;;:48;;;;103671:28;;;;;:12;:28;;;:43;;103700:13;;103671:43;;;;;;:::i;:::-;;;;;;;;;;;103716:13;103663:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102566:1172;;;;;;:::o;39069:402::-;39294:51;;;39283:10;22599:15:1;;;39294:51:0;;;22581:34:1;22651:15;;;22631:18;;;22624:43;22683:18;;;;22676:34;;;39294:51:0;;;;;;;;;;22493:18:1;;;;39294:51:0;;;;;;;;;;;;;39283:63;;-1:-1:-1;;;;39283:10:0;;;;:63;;39294:51;39283:63;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39247:99;;;;39365:7;:57;;;;-1:-1:-1;39377:11:0;;:16;;:44;;;39408:4;39397:24;;;;;;;;;;;;:::i;:::-;39357:106;;;;;;;22923:2:1;39357:106:0;;;22905:21:1;22962:2;22942:18;;;22935:30;23001:34;22981:18;;;22974:62;23072:6;23052:18;;;23045:34;23096:19;;39357:106:0;22721:400:1;39357:106:0;39157:314;;39069:402;;;;:::o;100602:1840::-;100748:7;100831:53;100842:14;100858:19;100879:4;100831:10;:53::i;:::-;;100938:28;100968:21;100993:33;101003:14;101019:6;100993:9;:33::i;:::-;100937:89;;;;101113:57;101129:14;101145:9;101156:13;101113:15;:57::i;:::-;-1:-1:-1;101239:26:0;;;;101097:73;;-1:-1:-1;101220:15:0;:45;;;:71;;-1:-1:-1;101269:14:0;;;;:22;;:14;:22;101220:71;:110;;;-1:-1:-1;101311:10:0;101295:27;;;;:15;:27;;;;;;;;:35;;:27;:35;101220:110;101212:145;;;;;;;23328:2:1;101212:145:0;;;23310:21:1;23367:2;23347:18;;;23340:30;23406:24;23386:18;;;23379:52;23448:18;;101212:145:0;23126:346:1;101212:145:0;101388:19;;;;101424:13;;101420:986;;101516:9;101489:23;;:36;;;;;;;:::i;:::-;;;;-1:-1:-1;;101540:33:0;;;;;;;:17;:33;;;;;:46;;101577:9;;101540:33;:46;;101577:9;;101540:46;:::i;:::-;;;;-1:-1:-1;101620:17:0;;-1:-1:-1;101640:27:0;101652:14;101640:11;:27::i;:::-;101620:47;-1:-1:-1;101690:23:0;;;;101686:70;;101715:28;;;;;;;:17;:28;;;;;:41;;101747:9;;101715:28;:41;;101747:9;;101715:41;:::i;:::-;;;;-1:-1:-1;;101686:70:0;-1:-1:-1;101843:28:0;;;;;;;:12;:28;;;;;:43;;101872:13;;101843:43;;;;;;:::i;:::-;;;;;;;;;;;;;;101836:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102015:12;;;:53;;;;;:12;17702:55:1;;;102015:53:0;;;17684:74:1;;;;17774:18;;;17767:34;;;102015:12:0;;;;;;;:21;;17657:18:1;;102015:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;102155:46;102179:14;102195:5;102155:23;:46::i;:::-;102308:70;;;23679:25:1;;;23735:2;23720:18;;23713:34;;;102308:70:0;23783:55:1;;;23763:18;;;23756:83;102308:70:0;;;;;;;;;;;23667:2:1;102308:70:0;;;101420:986;102425:9;100602:1840;-1:-1:-1;;;;;;100602:1840:0:o;71035:2569::-;71156:9;71151:327;71175:18;:25;71171:29;;71151:327;;;71222:34;71259:18;71278:1;71259:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;71299:40:0;;71295:172;;71360:91;;;;;71445:4;71360:91;;;4366:74:1;71360:76:0;;;;;;4339:18:1;;71360:91:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;71295:172;-1:-1:-1;71202:3:0;;;;:::i;:::-;;;;71151:327;;;;71838:27;52713:6;71894:12;;71876:15;:30;;;;:::i;:::-;71868:57;;;;:::i;:::-;71838:87;;72064:9;72059:283;72083:12;:19;72079:23;;72059:283;;;72204:12;72217:1;72204:15;;;;;;;;:::i;:::-;;;;;;;;;;;72198:47;;;;;72239:4;72198:47;;;4366:74:1;72204:15:0;;;;;72198:32;;4339:18:1;;72198:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72169:23;:19;72191:1;72169:23;:::i;:::-;52713:6;72133:14;72145:1;72133:11;:14::i;:::-;:32;;;;:::i;:::-;:60;;;;:::i;:::-;72132:113;;72311:12;72324:1;72311:15;;;;;;;;:::i;:::-;;;;;;;;;;;;72254:73;;;24342:34:1;72254:73:0;;;24330:47:1;;;;24407:6;24393:12;;;24386:28;24452:2;24448:15;;;24430:12;;;24423:110;24549:12;;72254:73:0;;;;;;;;;;;;72124:206;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;72104:3:0;;;;:::i;:::-;;;;72059:283;;;-1:-1:-1;52713:6:0;72554:23;:19;72576:1;72554:23;:::i;:::-;72553:43;;;;:::i;:::-;72537:12;;:60;;;;:::i;:::-;72522:12;:75;72650:29;:27;:29::i;:::-;90948:4;72731:15;:34;72963:17;:20;;72981:1;;72963:20;;;;;;:::i;:::-;;;;;;;;;72987:1;72963:25;72959:634;;73115:16;;;73129:1;73115:16;;;;;;;;;73085:27;;73115:16;;;;;;;;;;;-1:-1:-1;73115:16:0;73085:46;;73162:42;73146:10;73157:1;73146:13;;;;;;;;:::i;:::-;:58;;;;:13;;;;;;;;;;;:58;73251:262;;;;;73228:20;;73284:42;;73251:89;;:262;;73359:10;;73388:78;;73493:4;;73251:262;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73228:285;-1:-1:-1;73551:30:0;52713:6;73228:285;73551:30;:::i;:::-;73528:17;73546:1;73528:20;;;;;;;;:::i;:::-;;;;;;;;;;:53;-1:-1:-1;;71068:2536:0;71035:2569::o;73612:435::-;73699:34;73736:17;:15;:17::i;:::-;73699:54;;73816:9;73811:133;73835:21;:28;73831:32;;73811:133;;;73912:17;73930:1;73912:20;;;;;;;;:::i;:::-;;;;;;;73885:21;73907:1;73885:24;;;;;;;;:::i;:::-;;;;;;;;;;:47;73865:3;;;;:::i;:::-;;;;73811:133;;;;74013:26;:24;:26::i;:::-;73996:14;:43;-1:-1:-1;73612:435:0:o;68297:585::-;68359:21;;;;68355:520;;68436:27;68466:15;68473:7;68466:6;:15::i;:::-;68436:45;;68544:9;68539:118;68563:10;:17;68559:1;:21;68539:118;;;68628:10;68639:1;68628:13;;;;;;;;:::i;:::-;;;;;;;;;;;;68606:16;;;;;;;:7;:16;;;;;;:19;;;;;;;;;;:35;68623:1;68582:3;68623:1;68582:3;:::i;:::-;;;;68539:118;;;;68724:9;68719:145;68743:10;:17;68739:1;:21;68719:145;;;68824:21;68846:1;68824:24;;;;;;;;:::i;:::-;;;;;;;;;;;;;68786:32;;;;;:23;:32;;;;;;:35;;;;;;;;:62;68819:1;68762:3;68819:1;68762:3;:::i;:::-;;;;68719:145;;14:154:1;100:42;93:5;89:54;82:5;79:65;69:93;;158:1;155;148:12;173:247;232:6;285:2;273:9;264:7;260:23;256:32;253:52;;;301:1;298;291:12;253:52;340:9;327:23;359:31;384:5;359:31;:::i;425:632::-;596:2;648:21;;;718:13;;621:18;;;740:22;;;567:4;;596:2;819:15;;;;793:2;778:18;;;567:4;862:169;876:6;873:1;870:13;862:169;;;937:13;;925:26;;1006:15;;;;971:12;;;;898:1;891:9;862:169;;;-1:-1:-1;1048:3:1;;425:632;-1:-1:-1;;;;;;425:632:1:o;1062:180::-;1121:6;1174:2;1162:9;1153:7;1149:23;1145:32;1142:52;;;1190:1;1187;1180:12;1142:52;-1:-1:-1;1213:23:1;;1062:180;-1:-1:-1;1062:180:1:o;1429:484::-;1482:3;1520:5;1514:12;1547:6;1542:3;1535:19;1573:4;1602:2;1597:3;1593:12;1586:19;;1639:2;1632:5;1628:14;1660:1;1670:218;1684:6;1681:1;1678:13;1670:218;;;1749:13;;1764:42;1745:62;1733:75;;1828:12;;;;1863:15;;;;1706:1;1699:9;1670:218;;;-1:-1:-1;1904:3:1;;1429:484;-1:-1:-1;;;;;1429:484:1:o;1918:261::-;2097:2;2086:9;2079:21;2060:4;2117:56;2169:2;2158:9;2154:18;2146:6;2117:56;:::i;2184:248::-;2252:6;2260;2313:2;2301:9;2292:7;2288:23;2284:32;2281:52;;;2329:1;2326;2319:12;2281:52;-1:-1:-1;;2352:23:1;;;2422:2;2407:18;;;2394:32;;-1:-1:-1;2184:248:1:o;2619:1011::-;2848:2;2900:21;;;2970:13;;2873:18;;;2992:22;;;2819:4;;2848:2;3033;;3051:18;;;;3092:15;;;2819:4;3135:469;3149:6;3146:1;3143:13;3135:469;;;3208:13;;3246:9;;3234:22;;3296:11;;;3290:18;3276:12;;;3269:40;3349:11;;;3343:18;3329:12;;;3322:40;3385:4;3429:11;;;3423:18;3409:12;;;3402:40;3465:4;3509:11;;;3503:18;3489:12;;;3482:40;3551:4;3542:14;;;;3579:15;;;;3171:1;3164:9;3135:469;;;-1:-1:-1;3621:3:1;;2619:1011;-1:-1:-1;;;;;;;2619:1011:1:o;3635:388::-;3703:6;3711;3764:2;3752:9;3743:7;3739:23;3735:32;3732:52;;;3780:1;3777;3770:12;3732:52;3819:9;3806:23;3838:31;3863:5;3838:31;:::i;:::-;3888:5;-1:-1:-1;3945:2:1;3930:18;;3917:32;3958:33;3917:32;3958:33;:::i;:::-;4010:7;4000:17;;;3635:388;;;;;:::o;4451:452::-;4537:6;4545;4553;4561;4614:3;4602:9;4593:7;4589:23;4585:33;4582:53;;;4631:1;4628;4621:12;4582:53;4670:9;4657:23;4689:31;4714:5;4689:31;:::i;:::-;4739:5;4791:2;4776:18;;4763:32;;-1:-1:-1;4842:2:1;4827:18;;4814:32;;4893:2;4878:18;4865:32;;-1:-1:-1;4451:452:1;-1:-1:-1;;;4451:452:1:o;5155:118::-;5241:5;5234:13;5227:21;5220:5;5217:32;5207:60;;5263:1;5260;5253:12;5278:382;5343:6;5351;5404:2;5392:9;5383:7;5379:23;5375:32;5372:52;;;5420:1;5417;5410:12;5372:52;5459:9;5446:23;5478:31;5503:5;5478:31;:::i;:::-;5528:5;-1:-1:-1;5585:2:1;5570:18;;5557:32;5598:30;5557:32;5598:30;:::i;5665:315::-;5733:6;5741;5794:2;5782:9;5773:7;5769:23;5765:32;5762:52;;;5810:1;5807;5800:12;5762:52;5849:9;5836:23;5868:31;5893:5;5868:31;:::i;:::-;5918:5;5970:2;5955:18;;;;5942:32;;-1:-1:-1;;;5665:315:1:o;7215:511::-;7283:6;7291;7299;7352:2;7340:9;7331:7;7327:23;7323:32;7320:52;;;7368:1;7365;7358:12;7320:52;7407:9;7394:23;7426:28;7448:5;7426:28;:::i;:::-;7473:5;-1:-1:-1;7530:2:1;7515:18;;7502:32;7543:30;7502:32;7543:30;:::i;:::-;7592:7;-1:-1:-1;7651:2:1;7636:18;;7623:32;7664:30;7623:32;7664:30;:::i;:::-;7713:7;7703:17;;;7215:511;;;;;:::o;7731:598::-;7817:6;7825;7833;7841;7894:3;7882:9;7873:7;7869:23;7865:33;7862:53;;;7911:1;7908;7901:12;7862:53;7950:9;7937:23;7969:31;7994:5;7969:31;:::i;:::-;8019:5;-1:-1:-1;8071:2:1;8056:18;;8043:32;;-1:-1:-1;8127:2:1;8112:18;;8099:32;8140:33;8099:32;8140:33;:::i;:::-;8192:7;-1:-1:-1;8251:2:1;8236:18;;8223:32;8264:33;8223:32;8264:33;:::i;:::-;7731:598;;;;-1:-1:-1;7731:598:1;;-1:-1:-1;;7731:598:1:o;8334:315::-;8402:6;8410;8463:2;8451:9;8442:7;8438:23;8434:32;8431:52;;;8479:1;8476;8469:12;8431:52;8515:9;8502:23;8492:33;;8575:2;8564:9;8560:18;8547:32;8588:31;8613:5;8588:31;:::i;8974:241::-;9030:6;9083:2;9071:9;9062:7;9058:23;9054:32;9051:52;;;9099:1;9096;9089:12;9051:52;9138:9;9125:23;9157:28;9179:5;9157:28;:::i;9220:184::-;9272:77;9269:1;9262:88;9369:4;9366:1;9359:15;9393:4;9390:1;9383:15;9409:915;9491:6;9544:3;9532:9;9523:7;9519:23;9515:33;9512:53;;;9561:1;9558;9551:12;9512:53;9610:7;9603:4;9592:9;9588:20;9584:34;9574:62;;9632:1;9629;9622:12;9574:62;9665:2;9659:9;9707:3;9699:6;9695:16;9777:6;9765:10;9762:22;9741:18;9729:10;9726:34;9723:62;9720:242;;;9818:77;9815:1;9808:88;9919:4;9916:1;9909:15;9947:4;9944:1;9937:15;9720:242;9978:2;9971:22;10013:6;10057:3;10042:19;;10073;;;10070:39;;;10105:1;10102;10095:12;10070:39;10129:9;10147:146;10163:6;10158:3;10155:15;10147:146;;;10231:17;;10219:30;;10278:4;10269:14;;;;10180;10147:146;;;-1:-1:-1;10312:6:1;;9409:915;-1:-1:-1;;;;;9409:915:1:o;10329:184::-;10381:77;10378:1;10371:88;10478:4;10475:1;10468:15;10502:4;10499:1;10492:15;10518:184;10570:77;10567:1;10560:88;10667:4;10664:1;10657:15;10691:4;10688:1;10681:15;10707:125;10747:4;10775:1;10772;10769:8;10766:34;;;10780:18;;:::i;:::-;-1:-1:-1;10817:9:1;;10707:125::o;10837:228::-;10877:7;11003:1;10935:66;10931:74;10928:1;10925:81;10920:1;10913:9;10906:17;10902:105;10899:131;;;11010:18;;:::i;:::-;-1:-1:-1;11050:9:1;;10837:228::o;11070:274::-;11110:1;11136;11126:189;;11171:77;11168:1;11161:88;11272:4;11269:1;11262:15;11300:4;11297:1;11290:15;11126:189;-1:-1:-1;11329:9:1;;11070:274::o;11349:128::-;11389:3;11420:1;11416:6;11413:1;11410:13;11407:39;;;11426:18;;:::i;:::-;-1:-1:-1;11462:9:1;;11349:128::o;11482:195::-;11521:3;11552:66;11545:5;11542:77;11539:103;;11622:18;;:::i;:::-;-1:-1:-1;11669:1:1;11658:13;;11482:195::o;12458:251::-;12528:6;12581:2;12569:9;12560:7;12556:23;12552:32;12549:52;;;12597:1;12594;12587:12;12549:52;12629:9;12623:16;12648:31;12673:5;12648:31;:::i;12714:184::-;12784:6;12837:2;12825:9;12816:7;12812:23;12808:32;12805:52;;;12853:1;12850;12843:12;12805:52;-1:-1:-1;12876:16:1;;12714:184;-1:-1:-1;12714:184:1:o;20822:258::-;20894:1;20904:113;20918:6;20915:1;20912:13;20904:113;;;20994:11;;;20988:18;20975:11;;;20968:39;20940:2;20933:10;20904:113;;;21035:6;21032:1;21029:13;21026:48;;;-1:-1:-1;;21070:1:1;21052:16;;21045:27;20822:258::o;21085:274::-;21214:3;21252:6;21246:13;21268:53;21314:6;21309:3;21302:4;21294:6;21290:17;21268:53;:::i;:::-;21337:16;;;;;21085:274;-1:-1:-1;;21085:274:1:o;21364:245::-;21431:6;21484:2;21472:9;21463:7;21459:23;21455:32;21452:52;;;21500:1;21497;21490:12;21452:52;21532:9;21526:16;21551:28;21573:5;21551:28;:::i;23850:245::-;23929:6;23937;23990:2;23978:9;23969:7;23965:23;23961:32;23958:52;;;24006:1;24003;23996:12;23958:52;-1:-1:-1;;24029:16:1;;24085:2;24070:18;;;24064:25;24029:16;;24064:25;;-1:-1:-1;23850:245:1:o;24572:442::-;24721:2;24710:9;24703:21;24684:4;24753:6;24747:13;24796:6;24791:2;24780:9;24776:18;24769:34;24812:66;24871:6;24866:2;24855:9;24851:18;24846:2;24838:6;24834:15;24812:66;:::i;:::-;24930:2;24918:15;24935:66;24914:88;24899:104;;;;25005:2;24895:113;;24572:442;-1:-1:-1;;24572:442:1:o;25019:537::-;25339:2;25328:9;25321:21;25302:4;25359:56;25411:2;25400:9;25396:18;25388:6;25359:56;:::i;:::-;25351:64;;25451:6;25446:2;25435:9;25431:18;25424:34;25506:42;25498:6;25494:55;25489:2;25478:9;25474:18;25467:83;25019:537;;;;;;:::o
Swarm Source
ipfs://62234020a79da5894696814a693b51a31d672a6e51f17fa40d3cc3868dc56bea
Loading...
Loading
Loading...
Loading
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.