Contract Overview
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Latest 4 internal transactions
Parent Txn Hash | Block | From | To | Value | |||
---|---|---|---|---|---|---|---|
0xaa5d1514d0b03bd27da2a0a295bba3532e182f965f27a6b637191553d88050bf | 36415643 | 121 days 11 hrs ago | 0x7947aadff0f3a3b9862bfd3ba3c3e98ec9c50a72 | Fantom Finance: Wrapped Fantom Token | 10,586.28 FTM | ||
0x7ef4ef71ca3d56935b3110d3ed167d850ce883e49277e1421dda214f26ccf5cb | 36412487 | 121 days 12 hrs ago | 0xd9db270c1b5e3bd161e8c8503c55ceabee709552 | 0x7947aadff0f3a3b9862bfd3ba3c3e98ec9c50a72 | 10,586.28 FTM | ||
0x075a04e59f58e4f614ced6a30927dbc5131e0a6a2493cc64796fc82de89ac866 | 36341207 | 122 days 10 hrs ago | 0x7947aadff0f3a3b9862bfd3ba3c3e98ec9c50a72 | Fantom Finance: Wrapped Fantom Token | 15,740.1315 FTM | ||
0x084a772fc52e77685085df0877c0f746cd62164aa1c32006772ca84d738bfc42 | 33962608 | 150 days 15 hrs ago | 0x3b410908e71ee04e7de2a87f8f9003afe6c1c7ce | Contract Creation | 0 FTM |
[ Download CSV Export ]
Contract Name:
ReaperAutoCompoundBeethoven_fBEETS
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity Standard Json-Input format)
/** *Submitted for verification at FtmScan.com on 2021-11-26 */ /** *Submitted for verification at FtmScan.com on 2021-09-10 */ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File: @openzeppelin/contracts/access/Ownable.sol pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: @openzeppelin/contracts/token/ERC20/IERC20.sol pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File: @openzeppelin/contracts/math/SafeMath.sol pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // 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 (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @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) { return a + b; } /** * @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 a - b; } /** * @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) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting 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 a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting 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. */ function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * 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, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } } // File: @openzeppelin/contracts/utils/Address.sol pragma solidity ^0.8.0; /** * @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; 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"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } pragma solidity ^0.8.0; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // File: @openzeppelin/contracts/token/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 {ERC20PresetMinterPauser}. * * 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 Contracts guidelines: functions revert * instead 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, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override 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 this function is * overridden; * * 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 virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual 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. */ 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); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); unchecked { _approve(sender, _msgSender(), currentAllowance - amount); } 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] + 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) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(_msgSender(), spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `sender` to `recipient`. * * This 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); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[sender] = senderBalance - amount; } _balances[recipient] += amount; emit Transfer(sender, recipient, amount); _afterTokenTransfer(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: * * - `account` 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 += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This 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 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 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:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} } // File: @openzeppelin/contracts/token/ERC20/SafeERC20.sol pragma solidity ^0.8.0; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // File: @openzeppelin/contracts/utils/Pausable.sol pragma solidity ^0.8.0; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } } interface IAuthorizer { /** * @dev Returns true if `account` can perform the action described by `actionId` in the contract `where`. */ function canPerform( bytes32 actionId, address account, address where ) external view returns (bool); } interface IPoolToken { function getPoolTokens(bytes32 poolId) external returns ( IERC20[] memory, uint256[] memory, uint256 ); } interface IPoolSwapStructs { // This is not really an interface - it just defines common structs used by other interfaces: IGeneralPool and // IMinimalSwapInfoPool. // // This data structure represents a request for a token swap, where `kind` indicates the swap type ('given in' or // 'given out') which indicates whether or not the amount sent by the pool is known. // // The pool receives `tokenIn` and sends `tokenOut`. `amount` is the number of `tokenIn` tokens the pool will take // in, or the number of `tokenOut` tokens the Pool will send out, depending on the given swap `kind`. // // All other fields are not strictly necessary for most swaps, but are provided to support advanced scenarios in // some Pools. // // `poolId` is the ID of the Pool involved in the swap - this is useful for Pool contracts that implement more than // one Pool. // // The meaning of `lastChangeBlock` depends on the Pool specialization: // - Two Token or Minimal Swap Info: the last block in which either `tokenIn` or `tokenOut` changed its total // balance. // - General: the last block in which *any* of the Pool's registered tokens changed its total balance. // // `from` is the origin address for the funds the Pool receives, and `to` is the destination address // where the Pool sends the outgoing tokens. // // `userData` is extra data provided by the caller - typically a signature from a trusted party. struct SwapRequest { IVault.SwapKind kind; IERC20 tokenIn; IERC20 tokenOut; uint256 amount; // Misc data bytes32 poolId; uint256 lastChangeBlock; address from; address to; bytes userData; } } interface IBasePool is IPoolSwapStructs { /** * @dev Called by the Vault when a user calls `IVault.joinPool` to add liquidity to this Pool. Returns how many of * each registered token the user should provide, as well as the amount of protocol fees the Pool owes to the Vault. * The Vault will then take tokens from `sender` and add them to the Pool's balances, as well as collect * the reported amount in protocol fees, which the pool should calculate based on `protocolSwapFeePercentage`. * * Protocol fees are reported and charged on join events so that the Pool is free of debt whenever new users join. * * `sender` is the account performing the join (from which tokens will be withdrawn), and `recipient` is the account * designated to receive any benefits (typically pool shares). `balances` contains the total balances * for each token the Pool registered in the Vault, in the same order that `IVault.getPoolTokens` would return. * * `lastChangeBlock` is the last block in which *any* of the Pool's registered tokens last changed its total * balance. * * `userData` contains any pool-specific instructions needed to perform the calculations, such as the type of * join (e.g., proportional given an amount of pool shares, single-asset, multi-asset, etc.) * * Contracts implementing this function should check that the caller is indeed the Vault before performing any * state-changing operations, such as minting pool shares. */ function onJoinPool( bytes32 poolId, address sender, address recipient, uint256[] memory balances, uint256 lastChangeBlock, uint256 protocolSwapFeePercentage, bytes memory userData ) external returns (uint256[] memory amountsIn, uint256[] memory dueProtocolFeeAmounts); /** * @dev Called by the Vault when a user calls `IVault.exitPool` to remove liquidity from this Pool. Returns how many * tokens the Vault should deduct from the Pool's balances, as well as the amount of protocol fees the Pool owes * to the Vault. The Vault will then take tokens from the Pool's balances and send them to `recipient`, * as well as collect the reported amount in protocol fees, which the Pool should calculate based on * `protocolSwapFeePercentage`. * * Protocol fees are charged on exit events to guarantee that users exiting the Pool have paid their share. * * `sender` is the account performing the exit (typically the pool shareholder), and `recipient` is the account * to which the Vault will send the proceeds. `balances` contains the total token balances for each token * the Pool registered in the Vault, in the same order that `IVault.getPoolTokens` would return. * * `lastChangeBlock` is the last block in which *any* of the Pool's registered tokens last changed its total * balance. * * `userData` contains any pool-specific instructions needed to perform the calculations, such as the type of * exit (e.g., proportional given an amount of pool shares, single-asset, multi-asset, etc.) * * Contracts implementing this function should check that the caller is indeed the Vault before performing any * state-changing operations, such as burning pool shares. */ function onExitPool( bytes32 poolId, address sender, address recipient, uint256[] memory balances, uint256 lastChangeBlock, uint256 protocolSwapFeePercentage, bytes memory userData ) external returns (uint256[] memory amountsOut, uint256[] memory dueProtocolFeeAmounts); function getPoolId() external view returns (bytes32); } /** * @dev Pool contracts with the MinimalSwapInfo or TwoToken specialization settings should implement this interface. * * This is called by the Vault when a user calls `IVault.swap` or `IVault.batchSwap` to swap with this Pool. * Returns the number of tokens the Pool will grant to the user in a 'given in' swap, or that the user will grant * to the pool in a 'given out' swap. * * This can often be implemented by a `view` function, since many pricing algorithms don't need to track state * changes in swaps. However, contracts implementing this in non-view functions should check that the caller is * indeed the Vault. */ interface IMinimalSwapInfoPool is IBasePool { function onSwap( SwapRequest memory swapRequest, uint256 currentBalanceTokenIn, uint256 currentBalanceTokenOut ) external returns (uint256 amount); } interface IGeneralPool is IBasePool { function onSwap( SwapRequest memory swapRequest, uint256[] memory balances, uint256 indexIn, uint256 indexOut ) external returns (uint256 amount); } pragma solidity ^0.8.0; interface IMasterChef { function poolLength() external view returns (uint256); function getMultiplier(uint256 _from, uint256 _to) external view returns (uint256); function pendingSpirit(uint256 _pid, address _user) external view returns (uint256); function massUpdatePools() external; function updatePool(uint256 _pid) external; function deposit(uint256 _pid, uint256 _amount) external; function withdraw(uint256 _pid, uint256 _amount) external; function userInfo(uint256 _pid, address _user) external view returns (uint256, uint256); function emergencyWithdraw(uint256 _pid, address _to) external; } interface IMasterChefv2 { function harvest(uint256 pid, address to) external; function withdrawAndHarvest(uint256 pid, uint256 amount, address to) external; function deposit(uint256 pid, uint256 amount, address to) external; function beets() external view returns (uint256); } /** * @dev This is an empty interface used to represent either ERC20-conforming token contracts or ETH (using the zero * address sentinel value). We're just relying on the fact that `interface` can be used to declare new address-like * types. * * This concept is unrelated to a Pool's Asset Managers. */ interface IAsset { // solhint-disable-previous-line no-empty-blocks } /** * @dev Interface for the SignatureValidator helper, used to support meta-transactions. */ interface ISignaturesValidator { /** * @dev Returns the EIP712 domain separator. */ function getDomainSeparator() external view returns (bytes32); /** * @dev Returns the next nonce used by an address to sign messages. */ function getNextNonce(address user) external view returns (uint256); } interface ITemporarilyPausable { /** * @dev Emitted every time the pause state changes by `_setPaused`. */ event PausedStateChanged(bool paused); /** * @dev Returns the current paused state. */ function getPausedState() external view returns ( bool paused, uint256 pauseWindowEndTime, uint256 bufferPeriodEndTime ); } pragma solidity ^0.8.0; interface IVault is ISignaturesValidator, ITemporarilyPausable { // Generalities about the Vault: // // - Whenever documentation refers to 'tokens', it strictly refers to ERC20-compliant token contracts. Tokens are // transferred out of the Vault by calling the `IERC20.transfer` function, and transferred in by calling // `IERC20.transferFrom`. In these cases, the sender must have previously allowed the Vault to use their tokens by // calling `IERC20.approve`. The only deviation from the ERC20 standard that is supported is functions not returning // a boolean value: in these scenarios, a non-reverting call is assumed to be successful. // // - All non-view functions in the Vault are non-reentrant: calling them while another one is mid-execution (e.g. // while execution control is transferred to a token contract during a swap) will result in a revert. View // functions can be called in a re-reentrant way, but doing so might cause them to return inconsistent results. // Contracts calling view functions in the Vault must make sure the Vault has not already been entered. // // - View functions revert if referring to either unregistered Pools, or unregistered tokens for registered Pools. // Authorizer // // Some system actions are permissioned, like setting and collecting protocol fees. This permissioning system exists // outside of the Vault in the Authorizer contract: the Vault simply calls the Authorizer to check if the caller // can perform a given action. /** * @dev Returns the Vault's Authorizer. */ function getAuthorizer() external view returns (IAuthorizer); /** * @dev Sets a new Authorizer for the Vault. The caller must be allowed by the current Authorizer to do this. * * Emits an `AuthorizerChanged` event. */ function setAuthorizer(IAuthorizer newAuthorizer) external; /** * @dev Emitted when a new authorizer is set by `setAuthorizer`. */ event AuthorizerChanged(IAuthorizer indexed newAuthorizer); // Relayers // // Additionally, it is possible for an account to perform certain actions on behalf of another one, using their // Vault ERC20 allowance and Internal Balance. These accounts are said to be 'relayers' for these Vault functions, // and are expected to be smart contracts with sound authentication mechanisms. For an account to be able to wield // this power, two things must occur: // - The Authorizer must grant the account the permission to be a relayer for the relevant Vault function. This // means that Balancer governance must approve each individual contract to act as a relayer for the intended // functions. // - Each user must approve the relayer to act on their behalf. // This double protection means users cannot be tricked into approving malicious relayers (because they will not // have been allowed by the Authorizer via governance), nor can malicious relayers approved by a compromised // Authorizer or governance drain user funds, since they would also need to be approved by each individual user. /** * @dev Returns true if `user` has approved `relayer` to act as a relayer for them. */ function hasApprovedRelayer(address user, address relayer) external view returns (bool); /** * @dev Allows `relayer` to act as a relayer for `sender` if `approved` is true, and disallows it otherwise. * * Emits a `RelayerApprovalChanged` event. */ function setRelayerApproval( address sender, address relayer, bool approved ) external; /** * @dev Emitted every time a relayer is approved or disapproved by `setRelayerApproval`. */ event RelayerApprovalChanged(address indexed relayer, address indexed sender, bool approved); // Internal Balance // // Users can deposit tokens into the Vault, where they are allocated to their Internal Balance, and later // transferred or withdrawn. It can also be used as a source of tokens when joining Pools, as a destination // when exiting them, and as either when performing swaps. This usage of Internal Balance results in greatly reduced // gas costs when compared to relying on plain ERC20 transfers, leading to large savings for frequent users. // // Internal Balance management features batching, which means a single contract call can be used to perform multiple // operations of different kinds, with different senders and recipients, at once. /** * @dev Returns `user`'s Internal Balance for a set of tokens. */ function getInternalBalance(address user, IERC20[] memory tokens) external view returns (uint256[] memory); /** * @dev Performs a set of user balance operations, which involve Internal Balance (deposit, withdraw or transfer) * and plain ERC20 transfers using the Vault's allowance. This last feature is particularly useful for relayers, as * it lets integrators reuse a user's Vault allowance. * * For each operation, if the caller is not `sender`, it must be an authorized relayer for them. */ function manageUserBalance(UserBalanceOp[] memory ops) external payable; /** * @dev Data for `manageUserBalance` operations, which include the possibility for ETH to be sent and received without manual WETH wrapping or unwrapping. */ struct UserBalanceOp { UserBalanceOpKind kind; IAsset asset; uint256 amount; address sender; address payable recipient; } // There are four possible operations in `manageUserBalance`: // // - DEPOSIT_INTERNAL // Increases the Internal Balance of the `recipient` account by transferring tokens from the corresponding // `sender`. The sender must have allowed the Vault to use their tokens via `IERC20.approve()`. // // ETH can be used by passing the ETH sentinel value as the asset and forwarding ETH in the call: it will be wrapped // and deposited as WETH. Any ETH amount remaining will be sent back to the caller (not the sender, which is // relevant for relayers). // // Emits an `InternalBalanceChanged` event. // // // - WITHDRAW_INTERNAL // Decreases the Internal Balance of the `sender` account by transferring tokens to the `recipient`. // // ETH can be used by passing the ETH sentinel value as the asset. This will deduct WETH instead, unwrap it and send // it to the recipient as ETH. // // Emits an `InternalBalanceChanged` event. // // // - TRANSFER_INTERNAL // Transfers tokens from the Internal Balance of the `sender` account to the Internal Balance of `recipient`. // // Reverts if the ETH sentinel value is passed. // // Emits an `InternalBalanceChanged` event. // // // - TRANSFER_EXTERNAL // Transfers tokens from `sender` to `recipient`, using the Vault's ERC20 allowance. This is typically used by // relayers, as it lets them reuse a user's Vault allowance. // // Reverts if the ETH sentinel value is passed. // // Emits an `ExternalBalanceTransfer` event. enum UserBalanceOpKind { DEPOSIT_INTERNAL, WITHDRAW_INTERNAL, TRANSFER_INTERNAL, TRANSFER_EXTERNAL } /** * @dev Emitted when a user's Internal Balance changes, either from calls to `manageUserBalance`, or through * interacting with Pools using Internal Balance. * * Because Internal Balance works exclusively with ERC20 tokens, ETH deposits and withdrawals will use the WETH * address. */ event InternalBalanceChanged(address indexed user, IERC20 indexed token, int256 delta); /** * @dev Emitted when a user's Vault ERC20 allowance is used by the Vault to transfer tokens to an external account. */ event ExternalBalanceTransfer(IERC20 indexed token, address indexed sender, address recipient, uint256 amount); // Pools // // There are three specialization settings for Pools, which allow for cheaper swaps at the cost of reduced // functionality: // // - General: no specialization, suited for all Pools. IGeneralPool is used for swap request callbacks, passing the // balance of all tokens in the Pool. These Pools have the largest swap costs (because of the extra storage reads), // which increase with the number of registered tokens. // // - Minimal Swap Info: IMinimalSwapInfoPool is used instead of IGeneralPool, which saves gas by only passing the // balance of the two tokens involved in the swap. This is suitable for some pricing algorithms, like the weighted // constant product one popularized by Balancer V1. Swap costs are smaller compared to general Pools, and are // independent of the number of registered tokens. // // - Two Token: only allows two tokens to be registered. This achieves the lowest possible swap gas cost. Like // minimal swap info Pools, these are called via IMinimalSwapInfoPool. enum PoolSpecialization { GENERAL, MINIMAL_SWAP_INFO, TWO_TOKEN } /** * @dev Registers the caller account as a Pool with a given specialization setting. Returns the Pool's ID, which * is used in all Pool-related functions. Pools cannot be deregistered, nor can the Pool's specialization be * changed. * * The caller is expected to be a smart contract that implements either `IGeneralPool` or `IMinimalSwapInfoPool`, * depending on the chosen specialization setting. This contract is known as the Pool's contract. * * Note that the same contract may register itself as multiple Pools with unique Pool IDs, or in other words, * multiple Pools may share the same contract. * * Emits a `PoolRegistered` event. */ function registerPool(PoolSpecialization specialization) external returns (bytes32); /** * @dev Emitted when a Pool is registered by calling `registerPool`. */ event PoolRegistered(bytes32 indexed poolId, address indexed poolAddress, PoolSpecialization specialization); /** * @dev Returns a Pool's contract address and specialization setting. */ function getPool(bytes32 poolId) external view returns (address, PoolSpecialization); /** * @dev Registers `tokens` for the `poolId` Pool. Must be called by the Pool's contract. * * Pools can only interact with tokens they have registered. Users join a Pool by transferring registered tokens, * exit by receiving registered tokens, and can only swap registered tokens. * * Each token can only be registered once. For Pools with the Two Token specialization, `tokens` must have a length * of two, that is, both tokens must be registered in the same `registerTokens` call, and they must be sorted in * ascending order. * * The `tokens` and `assetManagers` arrays must have the same length, and each entry in these indicates the Asset * Manager for the corresponding token. Asset Managers can manage a Pool's tokens via `managePoolBalance`, * depositing and withdrawing them directly, and can even set their balance to arbitrary amounts. They are therefore * expected to be highly secured smart contracts with sound design principles, and the decision to register an * Asset Manager should not be made lightly. * * Pools can choose not to assign an Asset Manager to a given token by passing in the zero address. Once an Asset * Manager is set, it cannot be changed except by deregistering the associated token and registering again with a * different Asset Manager. * * Emits a `TokensRegistered` event. */ function registerTokens( bytes32 poolId, IERC20[] memory tokens, address[] memory assetManagers ) external; /** * @dev Emitted when a Pool registers tokens by calling `registerTokens`. */ event TokensRegistered(bytes32 indexed poolId, IERC20[] tokens, address[] assetManagers); /** * @dev Deregisters `tokens` for the `poolId` Pool. Must be called by the Pool's contract. * * Only registered tokens (via `registerTokens`) can be deregistered. Additionally, they must have zero total * balance. For Pools with the Two Token specialization, `tokens` must have a length of two, that is, both tokens * must be deregistered in the same `deregisterTokens` call. * * A deregistered token can be re-registered later on, possibly with a different Asset Manager. * * Emits a `TokensDeregistered` event. */ function deregisterTokens(bytes32 poolId, IERC20[] memory tokens) external; /** * @dev Emitted when a Pool deregisters tokens by calling `deregisterTokens`. */ event TokensDeregistered(bytes32 indexed poolId, IERC20[] tokens); /** * @dev Returns detailed information for a Pool's registered token. * * `cash` is the number of tokens the Vault currently holds for the Pool. `managed` is the number of tokens * withdrawn and held outside the Vault by the Pool's token Asset Manager. The Pool's total balance for `token` * equals the sum of `cash` and `managed`. * * Internally, `cash` and `managed` are stored using 112 bits. No action can ever cause a Pool's token `cash`, * `managed` or `total` balance to be greater than 2^112 - 1. * * `lastChangeBlock` is the number of the block in which `token`'s total balance was last modified (via either a * join, exit, swap, or Asset Manager update). This value is useful to avoid so-called 'sandwich attacks', for * example when developing price oracles. A change of zero (e.g. caused by a swap with amount zero) is considered a * change for this purpose, and will update `lastChangeBlock`. * * `assetManager` is the Pool's token Asset Manager. */ function getPoolTokenInfo(bytes32 poolId, IERC20 token) external view returns ( uint256 cash, uint256 managed, uint256 lastChangeBlock, address assetManager ); /** * @dev Returns a Pool's registered tokens, the total balance for each, and the latest block when *any* of * the tokens' `balances` changed. * * The order of the `tokens` array is the same order that will be used in `joinPool`, `exitPool`, as well as in all * Pool hooks (where applicable). Calls to `registerTokens` and `deregisterTokens` may change this order. * * If a Pool only registers tokens once, and these are sorted in ascending order, they will be stored in the same * order as passed to `registerTokens`. * * Total balances include both tokens held by the Vault and those withdrawn by the Pool's Asset Managers. These are * the amounts used by joins, exits and swaps. For a detailed breakdown of token balances, use `getPoolTokenInfo` * instead. */ function getPoolTokens(bytes32 poolId) external view returns ( IERC20[] memory tokens, uint256[] memory balances, uint256 lastChangeBlock ); /** * @dev Called by users to join a Pool, which transfers tokens from `sender` into the Pool's balance. This will * trigger custom Pool behavior, which will typically grant something in return to `recipient` - often tokenized * Pool shares. * * If the caller is not `sender`, it must be an authorized relayer for them. * * The `assets` and `maxAmountsIn` arrays must have the same length, and each entry indicates the maximum amount * to send for each asset. The amounts to send are decided by the Pool and not the Vault: it just enforces * these maximums. * * If joining a Pool that holds WETH, it is possible to send ETH directly: the Vault will do the wrapping. To enable * this mechanism, the IAsset sentinel value (the zero address) must be passed in the `assets` array instead of the * WETH address. Note that it is not possible to combine ETH and WETH in the same join. Any excess ETH will be sent * back to the caller (not the sender, which is important for relayers). * * `assets` must have the same length and order as the array returned by `getPoolTokens`. This prevents issues when * interacting with Pools that register and deregister tokens frequently. If sending ETH however, the array must be * sorted *before* replacing the WETH address with the ETH sentinel value (the zero address), which means the final * `assets` array might not be sorted. Pools with no registered tokens cannot be joined. * * If `fromInternalBalance` is true, the caller's Internal Balance will be preferred: ERC20 transfers will only * be made for the difference between the requested amount and Internal Balance (if any). Note that ETH cannot be * withdrawn from Internal Balance: attempting to do so will trigger a revert. * * This causes the Vault to call the `IBasePool.onJoinPool` hook on the Pool's contract, where Pools implement * their own custom logic. This typically requires additional information from the user (such as the expected number * of Pool shares). This can be encoded in the `userData` argument, which is ignored by the Vault and passed * directly to the Pool's contract, as is `recipient`. * * Emits a `PoolBalanceChanged` event. */ function joinPool( bytes32 poolId, address sender, address recipient, JoinPoolRequest memory request ) external payable; struct JoinPoolRequest { IAsset[] assets; uint256[] maxAmountsIn; bytes userData; bool fromInternalBalance; } /** * @dev Called by users to exit a Pool, which transfers tokens from the Pool's balance to `recipient`. This will * trigger custom Pool behavior, which will typically ask for something in return from `sender` - often tokenized * Pool shares. The amount of tokens that can be withdrawn is limited by the Pool's `cash` balance (see * `getPoolTokenInfo`). * * If the caller is not `sender`, it must be an authorized relayer for them. * * The `tokens` and `minAmountsOut` arrays must have the same length, and each entry in these indicates the minimum * token amount to receive for each token contract. The amounts to send are decided by the Pool and not the Vault: * it just enforces these minimums. * * If exiting a Pool that holds WETH, it is possible to receive ETH directly: the Vault will do the unwrapping. To * enable this mechanism, the IAsset sentinel value (the zero address) must be passed in the `assets` array instead * of the WETH address. Note that it is not possible to combine ETH and WETH in the same exit. * * `assets` must have the same length and order as the array returned by `getPoolTokens`. This prevents issues when * interacting with Pools that register and deregister tokens frequently. If receiving ETH however, the array must * be sorted *before* replacing the WETH address with the ETH sentinel value (the zero address), which means the * final `assets` array might not be sorted. Pools with no registered tokens cannot be exited. * * If `toInternalBalance` is true, the tokens will be deposited to `recipient`'s Internal Balance. Otherwise, * an ERC20 transfer will be performed. Note that ETH cannot be deposited to Internal Balance: attempting to * do so will trigger a revert. * * `minAmountsOut` is the minimum amount of tokens the user expects to get out of the Pool, for each token in the * `tokens` array. This array must match the Pool's registered tokens. * * This causes the Vault to call the `IBasePool.onExitPool` hook on the Pool's contract, where Pools implement * their own custom logic. This typically requires additional information from the user (such as the expected number * of Pool shares to return). This can be encoded in the `userData` argument, which is ignored by the Vault and * passed directly to the Pool's contract. * * Emits a `PoolBalanceChanged` event. */ function exitPool( bytes32 poolId, address sender, address payable recipient, ExitPoolRequest memory request ) external; struct ExitPoolRequest { IAsset[] assets; uint256[] minAmountsOut; bytes userData; bool toInternalBalance; } /** * @dev Emitted when a user joins or exits a Pool by calling `joinPool` or `exitPool`, respectively. */ event PoolBalanceChanged( bytes32 indexed poolId, address indexed liquidityProvider, IERC20[] tokens, int256[] deltas, uint256[] protocolFeeAmounts ); enum PoolBalanceChangeKind { JOIN, EXIT } // Swaps // // Users can swap tokens with Pools by calling the `swap` and `batchSwap` functions. To do this, // they need not trust Pool contracts in any way: all security checks are made by the Vault. They must however be // aware of the Pools' pricing algorithms in order to estimate the prices Pools will quote. // // The `swap` function executes a single swap, while `batchSwap` can perform multiple swaps in sequence. // In each individual swap, tokens of one kind are sent from the sender to the Pool (this is the 'token in'), // and tokens of another kind are sent from the Pool to the recipient in exchange (this is the 'token out'). // More complex swaps, such as one token in to multiple tokens out can be achieved by batching together // individual swaps. // // There are two swap kinds: // - 'given in' swaps, where the amount of tokens in (sent to the Pool) is known, and the Pool determines (via the // `onSwap` hook) the amount of tokens out (to send to the recipient). // - 'given out' swaps, where the amount of tokens out (received from the Pool) is known, and the Pool determines // (via the `onSwap` hook) the amount of tokens in (to receive from the sender). // // Additionally, it is possible to chain swaps using a placeholder input amount, which the Vault replaces with // the calculated output of the previous swap. If the previous swap was 'given in', this will be the calculated // tokenOut amount. If the previous swap was 'given out', it will use the calculated tokenIn amount. These extended // swaps are known as 'multihop' swaps, since they 'hop' through a number of intermediate tokens before arriving at // the final intended token. // // In all cases, tokens are only transferred in and out of the Vault (or withdrawn from and deposited into Internal // Balance) after all individual swaps have been completed, and the net token balance change computed. This makes // certain swap patterns, such as multihops, or swaps that interact with the same token pair in multiple Pools, cost // much less gas than they would otherwise. // // It also means that under certain conditions it is possible to perform arbitrage by swapping with multiple // Pools in a way that results in net token movement out of the Vault (profit), with no tokens being sent in (only // updating the Pool's internal accounting). // // To protect users from front-running or the market changing rapidly, they supply a list of 'limits' for each token // involved in the swap, where either the maximum number of tokens to send (by passing a positive value) or the // minimum amount of tokens to receive (by passing a negative value) is specified. // // Additionally, a 'deadline' timestamp can also be provided, forcing the swap to fail if it occurs after // this point in time (e.g. if the transaction failed to be included in a block promptly). // // If interacting with Pools that hold WETH, it is possible to both send and receive ETH directly: the Vault will do // the wrapping and unwrapping. To enable this mechanism, the IAsset sentinel value (the zero address) must be // passed in the `assets` array instead of the WETH address. Note that it is possible to combine ETH and WETH in the // same swap. Any excess ETH will be sent back to the caller (not the sender, which is relevant for relayers). // // Finally, Internal Balance can be used when either sending or receiving tokens. enum SwapKind { GIVEN_IN, GIVEN_OUT } /** * @dev Performs a swap with a single Pool. * * If the swap is 'given in' (the number of tokens to send to the Pool is known), it returns the amount of tokens * taken from the Pool, which must be greater than or equal to `limit`. * * If the swap is 'given out' (the number of tokens to take from the Pool is known), it returns the amount of tokens * sent to the Pool, which must be less than or equal to `limit`. * * Internal Balance usage and the recipient are determined by the `funds` struct. * * Emits a `Swap` event. */ function swap( SingleSwap memory singleSwap, FundManagement memory funds, uint256 limit, uint256 deadline ) external payable returns (uint256); /** * @dev Data for a single swap executed by `swap`. `amount` is either `amountIn` or `amountOut` depending on * the `kind` value. * * `assetIn` and `assetOut` are either token addresses, or the IAsset sentinel value for ETH (the zero address). * Note that Pools never interact with ETH directly: it will be wrapped to or unwrapped from WETH by the Vault. * * The `userData` field is ignored by the Vault, but forwarded to the Pool in the `onSwap` hook, and may be * used to extend swap behavior. */ struct SingleSwap { bytes32 poolId; SwapKind kind; IAsset assetIn; IAsset assetOut; uint256 amount; bytes userData; } /** * @dev Performs a series of swaps with one or multiple Pools. In each individual swap, the caller determines either * the amount of tokens sent to or received from the Pool, depending on the `kind` value. * * Returns an array with the net Vault asset balance deltas. Positive amounts represent tokens (or ETH) sent to the * Vault, and negative amounts represent tokens (or ETH) sent by the Vault. Each delta corresponds to the asset at * the same index in the `assets` array. * * Swaps are executed sequentially, in the order specified by the `swaps` array. Each array element describes a * Pool, the token to be sent to this Pool, the token to receive from it, and an amount that is either `amountIn` or * `amountOut` depending on the swap kind. * * Multihop swaps can be executed by passing an `amount` value of zero for a swap. This will cause the amount in/out * of the previous swap to be used as the amount in for the current one. In a 'given in' swap, 'tokenIn' must equal * the previous swap's `tokenOut`. For a 'given out' swap, `tokenOut` must equal the previous swap's `tokenIn`. * * The `assets` array contains the addresses of all assets involved in the swaps. These are either token addresses, * or the IAsset sentinel value for ETH (the zero address). Each entry in the `swaps` array specifies tokens in and * out by referencing an index in `assets`. Note that Pools never interact with ETH directly: it will be wrapped to * or unwrapped from WETH by the Vault. * * Internal Balance usage, sender, and recipient are determined by the `funds` struct. The `limits` array specifies * the minimum or maximum amount of each token the vault is allowed to transfer. * * `batchSwap` can be used to make a single swap, like `swap` does, but doing so requires more gas than the * equivalent `swap` call. * * Emits `Swap` events. */ function batchSwap( SwapKind kind, BatchSwapStep[] memory swaps, IAsset[] memory assets, FundManagement memory funds, int256[] memory limits, uint256 deadline ) external payable returns (int256[] memory); /** * @dev Data for each individual swap executed by `batchSwap`. The asset in and out fields are indexes into the * `assets` array passed to that function, and ETH assets are converted to WETH. * * If `amount` is zero, the multihop mechanism is used to determine the actual amount based on the amount in/out * from the previous swap, depending on the swap kind. * * The `userData` field is ignored by the Vault, but forwarded to the Pool in the `onSwap` hook, and may be * used to extend swap behavior. */ struct BatchSwapStep { bytes32 poolId; uint256 assetInIndex; uint256 assetOutIndex; uint256 amount; bytes userData; } /** * @dev Emitted for each individual swap performed by `swap` or `batchSwap`. */ event Swap( bytes32 indexed poolId, IERC20 indexed tokenIn, IERC20 indexed tokenOut, uint256 amountIn, uint256 amountOut ); /** * @dev All tokens in a swap are either sent from the `sender` account to the Vault, or from the Vault to the * `recipient` account. * * If the caller is not `sender`, it must be an authorized relayer for them. * * If `fromInternalBalance` is true, the `sender`'s Internal Balance will be preferred, performing an ERC20 * transfer for the difference between the requested amount and the User's Internal Balance (if any). The `sender` * must have allowed the Vault to use their tokens via `IERC20.approve()`. This matches the behavior of * `joinPool`. * * If `toInternalBalance` is true, tokens will be deposited to `recipient`'s internal balance instead of * transferred. This matches the behavior of `exitPool`. * * Note that ETH cannot be deposited to or withdrawn from Internal Balance: attempting to do so will trigger a * revert. */ struct FundManagement { address sender; bool fromInternalBalance; address payable recipient; bool toInternalBalance; } /** * @dev Simulates a call to `batchSwap`, returning an array of Vault asset deltas. Calls to `swap` cannot be * simulated directly, but an equivalent `batchSwap` call can and will yield the exact same result. * * Each element in the array corresponds to the asset at the same index, and indicates the number of tokens (or ETH) * the Vault would take from the sender (if positive) or send to the recipient (if negative). The arguments it * receives are the same that an equivalent `batchSwap` call would receive. * * Unlike `batchSwap`, this function performs no checks on the sender or recipient field in the `funds` struct. * This makes it suitable to be called by off-chain applications via eth_call without needing to hold tokens, * approve them for the Vault, or even know a user's address. * * Note that this function is not 'view' (due to implementation details): the client code must explicitly execute * eth_call instead of eth_sendTransaction. */ function queryBatchSwap( SwapKind kind, BatchSwapStep[] memory swaps, IAsset[] memory assets, FundManagement memory funds ) external returns (int256[] memory assetDeltas); // Asset Management // // Each token registered for a Pool can be assigned an Asset Manager, which is able to freely withdraw the Pool's // tokens from the Vault, deposit them, or assign arbitrary values to its `managed` balance (see // `getPoolTokenInfo`). This makes them extremely powerful and dangerous. Even if an Asset Manager only directly // controls one of the tokens in a Pool, a malicious manager could set that token's balance to manipulate the // prices of the other tokens, and then drain the Pool with swaps. The risk of using Asset Managers is therefore // not constrained to the tokens they are managing, but extends to the entire Pool's holdings. // // However, a properly designed Asset Manager smart contract can be safely used for the Pool's benefit, // for example by lending unused tokens out for interest, or using them to participate in voting protocols. // // This concept is unrelated to the IAsset interface. /** * @dev Performs a set of Pool balance operations, which may be either withdrawals, deposits or updates. * * Pool Balance management features batching, which means a single contract call can be used to perform multiple * operations of different kinds, with different Pools and tokens, at once. * * For each operation, the caller must be registered as the Asset Manager for `token` in `poolId`. */ function managePoolBalance(PoolBalanceOp[] memory ops) external; struct PoolBalanceOp { PoolBalanceOpKind kind; bytes32 poolId; IERC20 token; uint256 amount; } /** * Withdrawals decrease the Pool's cash, but increase its managed balance, leaving the total balance unchanged. * * Deposits increase the Pool's cash, but decrease its managed balance, leaving the total balance unchanged. * * Updates don't affect the Pool's cash balance, but because the managed balance changes, it does alter the total. * The external amount can be either increased or decreased by this call (i.e., reporting a gain or a loss). */ enum PoolBalanceOpKind { WITHDRAW, DEPOSIT, UPDATE } /** * @dev Emitted when a Pool's token Asset Manager alters its balance via `managePoolBalance`. */ event PoolBalanceManaged( bytes32 indexed poolId, address indexed assetManager, IERC20 indexed token, int256 cashDelta, int256 managedDelta ); // Protocol Fees // // Some operations cause the Vault to collect tokens in the form of protocol fees, which can then be withdrawn by // permissioned accounts. // // There are two kinds of protocol fees: // // - flash loan fees: charged on all flash loans, as a percentage of the amounts lent. // // - swap fees: a percentage of the fees charged by Pools when performing swaps. For a number of reasons, including // swap gas costs and interface simplicity, protocol swap fees are not charged on each individual swap. Rather, // Pools are expected to keep track of how much they have charged in swap fees, and pay any outstanding debts to the // Vault when they are joined or exited. This prevents users from joining a Pool with unpaid debt, as well as // exiting a Pool in debt without first paying their share. /** * @dev Safety mechanism to pause most Vault operations in the event of an emergency - typically detection of an * error in some part of the system. * * The Vault can only be paused during an initial time period, after which pausing is forever disabled. * * While the contract is paused, the following features are disabled: * - depositing and transferring internal balance * - transferring external balance (using the Vault's allowance) * - swaps * - joining Pools * - Asset Manager interactions * * Internal Balance can still be withdrawn, and Pools exited. */ function setPaused(bool paused) external; /** * @dev Returns the Vault's WETH instance. */ } interface IBaseWeightedPool { enum JoinKind { INIT, EXACT_TOKENS_IN_FOR_BPT_OUT, TOKEN_IN_FOR_EXACT_BPT_OUT, ALL_TOKENS_IN_FOR_EXACT_BPT_OUT } enum ExitKind { EXACT_BPT_IN_FOR_ONE_TOKEN_OUT, EXACT_BPT_IN_FOR_TOKENS_OUT, BPT_IN_FOR_EXACT_TOKENS_OUT, MANAGEMENT_FEE_TOKENS_OUT // for InvestmentPool } function getNormalizedWeights() external view returns (uint256[] memory); } interface IBeetsBar{ function enter(uint256 amount) external; function leave(uint256 amount) external; } interface IDelegateRegistry { function clearDelegate(bytes32 id) external; function delegation(address, bytes32) external view returns (address); function setDelegate(bytes32 id, address delegate) external; } interface IUniRouterMinimal { function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external; } interface IWrappedNative is IERC20 { function ERR_INVALID_ZERO_VALUE() external view returns (uint256); function ERR_NO_ERROR() external view returns (uint256); function deposit() external payable returns (uint256); function withdraw(uint256 amount) external returns (uint256); } interface IRFVault { function getPricePerFullShare() external view returns (uint256); } pragma solidity ^0.8.0; /** * @dev Implementation of a strategy to get yields from farming LP Pools in SpookySwap. * SpookySwap is an automated market maker (“AMM”) that allows two tokens to be exchanged on Fantom's Opera Network. * * This strategy deposits whatever funds it receives from the vault into the selected masterChef pool. * rewards from providing liquidity are farmed every few minutes, sold and split 50/50. * The corresponding pair of assets are bought and more liquidity is added to the masterChef pool. * * Expect the amount of LP tokens you have to grow over time while you have assets deposit */ contract ReaperAutoCompoundBeethoven_fBEETS is Ownable, Pausable { using SafeERC20 for IERC20; using Address for address; using SafeMath for uint256; /** * @dev Tokens Used: * {wftm} - Required for liquidity routing when doing swaps. * {rewardToken} - Token generated by staking our funds. * {lpToken} - LP Token that the strategy maximizes. * {lpToken0, lpToken1} - Tokens that the strategy maximizes. IUniswapV2Pair tokens. */ address public constant wftm = address(0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83); address public constant underlyingLP = address(0xcdE5a11a4ACB4eE4c805352Cec57E236bdBC3837); address public constant fBEETS = address(0xfcef8a994209d6916EB2C86cDD2AFD60Aa6F54b1); address public constant rewardToken = address(0xF24Bcf4d1e507740041C9cFd2DddB29585aDCe1e);// beets token address public constant BeetVault = address(0x20dd72Ed959b6147912C2e529F0a0C651c33c9ce); address public lpToken; uint8 public totalUnderlyingTokens; mapping(uint8 => bool) public isEmitting; bool public harvestOn = false; bool public depositsPaused = false; /** * @dev Third Party Contracts: * {router} - the router for target DEX * {masterChef} - masterChef contract * {poolId} - masterChef pool id */ address public masterChef = address(0x8166994d9ebBe5829EC86Bd81258149B87faCfd3); uint public poolId; bytes32 public poolID_bytes; uint8 public beetsPosition = 0; uint8 public wftmPosition = 0; bool public beetsUnderlying = false; bool public wftmUnderlying = false; bytes32 public route_ID; bytes32 public constant wftmRoute_ID = 0xcde5a11a4acb4ee4c805352cec57e236bdbc3837000200000000000000000019; bool public secondReward = false; address public secondRewardToken; bytes32 public secondRewardRoute; struct Harvest { uint256 timestamp; uint256 vaultSharePrice; } Harvest[] public harvestLog; uint256 public harvestLogCadence = 1 hours; uint256 public constant ONE_YEAR = 365 days; /** * @dev Reaper Contracts: * {treasury} - Address of the Reaper treasury * {vault} - Address of the vault that controls the strategy's funds. */ address public treasury; address public vault; address public strategistRemitter; /** * @dev Distribution of fees earned. This allocations relative to the % implemented on * Current implementation separates 5% for fees. Can be changed through the constructor * Inputs in constructor should be ratios between the Fee and Max Fee, divisble into percents by 10000 * * {callFee} - Percent of the totalFee reserved for the harvester (1000 = 10% of total fee: 0.5% by default) * {treasuryFee} - Percent of the totalFee taken by maintainers of the software (9000 = 90% of total fee: 4.5% by default) * {securityFee} - Fee taxed when a user withdraws funds. Taken to prevent flash deposit/harvest attacks. * These funds are redistributed to stakers in the pool. * * {totalFee} - divided by 10,000 to determine the % fee. Set to 5% by default and * lowered as necessary to provide users with the most competitive APY. * * {MAX_FEE} - Maximum fee allowed by the strategy. Hard-capped at 5%. * {PERCENT_DIVISOR} - Constant used to safely calculate the correct percentages. */ uint public callFee = 1000; uint public treasuryFee = 9000; uint256 public strategistFee = 2500; uint public securityFee = 10; uint public totalFee = 450; uint constant public MAX_FEE = 500; uint256 public constant STRATEGIST_MAX_FEE = 5000; uint constant public PERCENT_DIVISOR = 10000; /** * @dev Routes we take to swap tokens using PanrewardTokenSwap. * {rewardTokenToWftmRoute} - Route we take to get from {rewardToken} into {wftm}. * {rewardTokenToLp0Route} - Route we take to get from {rewardToken} into {lpToken0}. * {rewardTokenToLp1Route} - Route we take to get from {rewardToken} into {lpToken1}. */ mapping (uint8 => address) public LPs; /** * {StratHarvest} Event that is fired each time someone harvests the strat. * {TotalFeeUpdated} Event that is fired each time the total fee is updated. * {CallFeeUpdated} Event that is fired each time the call fee is updated. */ event StratHarvest(address indexed harvester); event TotalFeeUpdated(uint newFee); event CallFeeUpdated(uint newCallFee, uint newTreasuryFee); /** * @dev Initializes the strategy. Sets parameters, saves routes, and gives allowances. * @notice see documentation for each variable above its respective declaration. */ constructor ( address _lpToken, uint _poolId, address _vault, address _treasury, address _strategistRemitter ) public { lpToken = _lpToken; poolId = _poolId; poolID_bytes = wftmRoute_ID; vault = _vault; treasury = _treasury; strategistRemitter = _strategistRemitter; //gather underlying tokens //we're assuming we are dealing with the PoolTokens.sol for the interface IERC20[] memory _lps; (_lps,,) = IVault(BeetVault).getPoolTokens(poolID_bytes); totalUnderlyingTokens = uint8(_lps.length); for(uint8 i; i < _lps.length; i++){ LPs[i] = address(_lps[i]); if(LPs[i] == wftm){ wftmPosition = i; wftmUnderlying = true; } if(LPs[i] == rewardToken){ beetsPosition = i; beetsUnderlying = true; } } _giveAllowances(); //this will also need work harvestLog.push(Harvest({timestamp: block.timestamp, vaultSharePrice: IRFVault(_vault).getPricePerFullShare()})); } /** * @dev Function that puts the funds to work. * It gets called whenever someone deposits in the strategy's vault contract. * It deposits {lpToken} in the masterChef to farm {rewardToken} */ function deposit() external { require(!depositsPaused, "cannot deposit at this time"); _deposit(); } function _deposit() internal whenNotPaused onActionHarvest{ uint256 pairBal = IERC20(lpToken).balanceOf(address(this)); if (pairBal > 0) { IMasterChefv2(masterChef).deposit(poolId, pairBal, address(this)); } } /** * @dev Withdraws funds and sents them back to the vault. * It withdraws {lpToken} from the masterChef. * The available {lpToken} minus fees is returned to the vault. */ function withdraw(uint256 _amount) external onActionHarvest{ require(msg.sender == vault, "!vault"); uint256 pairBal = IERC20(lpToken).balanceOf(address(this)); if (pairBal < _amount) { IMasterChefv2(masterChef).withdrawAndHarvest(poolId, _amount.sub(pairBal), address(this)); pairBal = IERC20(lpToken).balanceOf(address(this)); } if (pairBal > _amount) { pairBal = _amount; } uint256 withdrawFee = pairBal.mul(securityFee).div(PERCENT_DIVISOR); IERC20(lpToken).safeTransfer(vault, pairBal.sub(withdrawFee)); } function harvest() external { _harvest(false); } /** * @dev Core function of the strat, in charge of collecting and re-investing rewards. * 1. It claims rewards from the masterChef. * 2. It charges the system fees to simplify the split. * 3. It swaps the {rewardToken} token for {lpToken0} & {lpToken1} * 4. Adds more liquidity to the pool. * 5. It deposits the new LP tokens. */ function _harvest(bool _remitStrategist) internal whenNotPaused { IMasterChefv2(masterChef).harvest(poolId, address(this)); _chargeFees(_remitStrategist); if(secondReward){_swapSecondToken(secondRewardToken, secondRewardRoute);} _addLiquidity(rewardToken, beetsPosition); _enterX(); _deposit(); if (block.timestamp >= harvestLog[harvestLog.length - 1].timestamp + harvestLogCadence) { harvestLog.push( Harvest({timestamp: block.timestamp, vaultSharePrice: IRFVault(vault).getPricePerFullShare()}) ); } emit StratHarvest(msg.sender); } function _enterX() internal { uint256 amtLP = IERC20(underlyingLP).balanceOf(address(this)); IBeetsBar(fBEETS).enter(amtLP); } /** * @dev Takes out fees from the rewards. Set by constructor * callFeeToUser is set as a percentage of the fee, * as is treasuryFeeToVault */ function _chargeFees(bool _remitStrategist) internal { uint256 rewardBal = IERC20(rewardToken).balanceOf(address(this)); uint256 wftmBal = IERC20(wftm).balanceOf(address(this)); uint256 fees; uint256 wftmFees; fees = rewardBal.mul(totalFee).div(PERCENT_DIVISOR); _swap(rewardToken, wftm, wftmRoute_ID, fees); wftmFees = IERC20(wftm).balanceOf(address(this)).sub(wftmBal); uint256 callFeeToUser = wftmFees.mul(callFee).div(PERCENT_DIVISOR); IERC20(wftm).safeTransfer(msg.sender, callFeeToUser); uint256 treasuryFeeToVault = wftmFees.mul(treasuryFee).div(PERCENT_DIVISOR); if (_remitStrategist) { uint256 feeToStrategist = treasuryFeeToVault.mul(strategistFee).div(PERCENT_DIVISOR); treasuryFeeToVault = treasuryFeeToVault.sub(feeToStrategist); IERC20(wftm).safeTransfer(strategistRemitter, feeToStrategist); } IERC20(wftm).safeTransfer(treasury, treasuryFeeToVault); } //function to swap from one token to another given a pool containing them both function _swap(address _tokenIN, address _tokenOUT, bytes32 _pool, uint256 amount) internal{ IVault.SingleSwap memory singleSwap; IVault.SwapKind swapKind = IVault.SwapKind.GIVEN_IN; singleSwap.poolId = _pool; singleSwap.kind = swapKind; singleSwap.assetIn = IAsset(_tokenIN); singleSwap.assetOut = IAsset(_tokenOUT); singleSwap.amount = amount; singleSwap.userData = abi.encode(0); IVault.FundManagement memory funds; funds.sender = address(this); funds.fromInternalBalance = false; funds.recipient = payable(address(this)); funds.toInternalBalance = false; IERC20(_tokenIN).safeApprove(BeetVault, 0); IERC20(_tokenIN).safeApprove(BeetVault, amount); IVault(BeetVault).swap(singleSwap, funds, 1, (block.timestamp + 600)); } /** * @dev Swaps {rewardToken} for {lpToken0}, {lpToken1} & {wftm} using SpookySwap. */ function _addLiquidity(address token, uint8 position) internal { uint256 depositTokenBalance = IERC20(token).balanceOf(address(this)); IERC20(token).safeApprove(BeetVault, 0); IERC20(token).safeApprove(BeetVault, depositTokenBalance); IBaseWeightedPool.JoinKind joinKind = IBaseWeightedPool.JoinKind.EXACT_TOKENS_IN_FOR_BPT_OUT; uint256[] memory amountsIn = new uint256[](totalUnderlyingTokens); amountsIn[position] = depositTokenBalance; uint256 minAmountOut = 1; IAsset[] memory _assets = new IAsset[](totalUnderlyingTokens); for(uint8 i = 0; i < totalUnderlyingTokens; i++){ _assets[i] = IAsset(LPs[i]); } bytes memory userData = abi.encode(joinKind, amountsIn, minAmountOut); IVault.JoinPoolRequest memory request; request.assets = _assets; request.maxAmountsIn = amountsIn; request.userData = userData; request.fromInternalBalance = false; IVault(BeetVault).joinPool( poolID_bytes, address(this), address(this), request ); } /** * @dev Function to calculate the total underlaying {lpToken} held by the strat. * It takes into account both the funds in hand, as the funds allocated in the masterChef. */ function balanceOf() public view returns (uint256) { return balanceOfLpPair().add(balanceOfPool()); } /** * @dev It calculates how much {lpToken} the contract holds. */ function balanceOfLpPair() public view returns (uint256) { return IERC20(lpToken).balanceOf(address(this)); } /** * @dev It calculates how much {lpToken} the strategy has allocated in the masterChef */ function balanceOfPool() public view returns (uint256) { (uint256 _amount,) = IMasterChef(masterChef).userInfo(poolId, address(this)); return _amount; } /** * @dev Function that has to be called as part of strat migration. It sends all the available funds back to the * vault, ready to be migrated to the new strat. */ function retireStrat() external { require(msg.sender == vault, "!vault"); IMasterChefv2(masterChef).withdrawAndHarvest(poolId, balanceOfPool(), address(this)); uint256 pairBal = IERC20(lpToken).balanceOf(address(this)); IERC20(lpToken).transfer(vault, pairBal); } /** * @dev Pauses deposits. Withdraws all funds from the masterChef, leaving rewards behind */ function panic() public onlyOwner { pause(); IMasterChef(masterChef).emergencyWithdraw(poolId, address(this)); } /** * @dev Pauses the strat. */ function pause() public onlyOwner { _pause(); _removeAllowances(); } /** * @dev Unpauses the strat. */ function unpause() external onlyOwner { _unpause(); _giveAllowances(); _deposit(); } function _giveAllowances() internal { IERC20(underlyingLP).safeApprove(fBEETS, 0); IERC20(rewardToken).safeApprove(BeetVault, 0); IERC20(wftm).safeApprove(BeetVault, 0); IERC20(fBEETS).safeApprove(masterChef, 0); IERC20(underlyingLP).safeApprove(fBEETS, type(uint256).max); IERC20(rewardToken).safeApprove(BeetVault, type(uint256).max); IERC20(wftm).safeApprove(BeetVault, type(uint256).max); IERC20(fBEETS).safeApprove(masterChef, type(uint256).max); } function _removeAllowances() internal { IERC20(underlyingLP).safeApprove(fBEETS, 0); IERC20(rewardToken).safeApprove(BeetVault, 0); IERC20(wftm).safeApprove(BeetVault, 0); IERC20(fBEETS).safeApprove(masterChef, 0); } /** * @dev updates the total fee, capped at 5% */ function updateTotalFee(uint _totalFee) external onlyOwner returns (bool) { require(_totalFee <= MAX_FEE, "Fee Too High"); totalFee = _totalFee; emit TotalFeeUpdated(totalFee); return true; } /** * @dev updates the strategist fee, capped at 50% of treasury fee */ function updateStrategistFee(uint256 _strategistFee) external onlyOwner { require(_strategistFee <= STRATEGIST_MAX_FEE, "Fee Too High"); strategistFee = _strategistFee; } /** * @dev updates the call fee and adjusts the treasury fee to cover the difference */ function updateCallFee(uint _callFee) external onlyOwner returns (bool) { callFee = _callFee; treasuryFee = PERCENT_DIVISOR.sub(callFee); emit CallFeeUpdated(callFee, treasuryFee); return true; } function harvestOnAction(bool _setting) external onlyOwner returns (bool){ harvestOn = _setting; return true; } modifier onActionHarvest { if (harvestOn == true){ _harvest(false); } _; } function updateRouteID(bytes32 newID) external onlyOwner { route_ID = newID; } function updateTreasury(address newTreasury) external onlyOwner returns (bool) { treasury = newTreasury; return true; } function _swapSecondToken(address token, bytes32 route) internal { uint256 wftmBal = IERC20(wftm).balanceOf(address(this)); uint256 bal = IERC20(token).balanceOf(address(this)); _swap(token, wftm, route, bal); uint256 fees = IERC20(wftm).balanceOf(address(this)).sub(wftmBal).mul(totalFee).div(PERCENT_DIVISOR); uint256 callFeeToUser = fees.mul(callFee).div(PERCENT_DIVISOR); IERC20(wftm).safeTransfer(msg.sender, callFeeToUser); uint256 treasuryFeeToVault = fees.mul(treasuryFee).div(PERCENT_DIVISOR); IERC20(wftm).safeTransfer(treasury, treasuryFeeToVault); wftmBal = IERC20(wftm).balanceOf(address(this)); _swap(wftm, rewardToken, wftmRoute_ID, wftmBal); } // NOTE: this is a centralized, high trust function used to securely deliver a secondary reward payload to users in the vault // Please ensure anyone operating clones of this vault are trustworthy before putting your money in function secondRewardInformation(bool status, address token, bytes32 route) external onlyOwner { require(token != rewardToken, "rewardToken is already accounted for"); secondReward = status; secondRewardToken = token; secondRewardRoute = route; } function updateSecurityFee(uint256 _fee) external onlyOwner { require(_fee <= 10, "fee too high"); securityFee = _fee; } // #################################################### // ONLY-OWNER VOTING/BRIBE-RELATED FUNCTIONS // #################################################### function setDepositsPaused(bool _depositsPaused) external onlyOwner { depositsPaused = _depositsPaused; } function setDelegate(address _registry, bytes32 _id, address _delegate) external onlyOwner { IDelegateRegistry(_registry).setDelegate(_id, _delegate); } // swaps {_tokens[0]} to {rewardToken} using {_routes} (series of Beethoven swaps) function swapBribeToken(address[] calldata _tokens, bytes32[] calldata _routes) external onlyOwner { require(_tokens.length != 0 && _tokens.length == _routes.length, "bad arrays"); for(uint256 i = 0; i < _tokens.length; i++) { address nextToken; if (i == _tokens.length - 1) { nextToken = rewardToken; } else { nextToken = _tokens[i + 1]; } _swap(_tokens[i], nextToken, _routes[i], IERC20(_tokens[i]).balanceOf(address(this))); } _harvest(true); // charge strategist fee } // swaps {_path[0]} to {rewardToken} using {_path} (Uni router swap) function swapBribeTokenWithUniRouter(address _router, address[] calldata _path) external onlyOwner { IERC20 token = IERC20(_path[0]); uint256 tokenBal = token.balanceOf(address(this)); token.safeIncreaseAllowance(_router, tokenBal); IUniRouterMinimal(_router).swapExactTokensForTokensSupportingFeeOnTransferTokens( tokenBal, 0, _path, address(this), block.timestamp + 600 ); _harvest(true); // charge strategist fee } function wrapNativeBribe(address _wrappedNative) external onlyOwner { IWrappedNative wrapped = IWrappedNative(_wrappedNative); uint256 balance = address(this).balance; require(wrapped.deposit{value: balance}() == wrapped.ERR_NO_ERROR(), "wrapping error"); } receive() external payable { } // #################################################### // ON-CHAIN APR CALCULATION FUNCTIONS // #################################################### function updateHarvestLogCadence(uint256 _newCadenceInSeconds) external onlyOwner { harvestLogCadence = _newCadenceInSeconds; } function harvestLogLength() external view returns (uint256) { return harvestLog.length; } /** * @dev Returns a slice of the harvest log containing the _n latest harvests. */ function latestHarvestLogSlice(uint256 _n) external view returns (Harvest[] memory slice) { slice = new Harvest[](_n); uint256 sliceCounter = 0; for (uint256 i = harvestLog.length - _n; i < harvestLog.length; i++) { slice[sliceCounter++] = harvestLog[i]; } } /** * @dev Traverses the harvest log backwards until it hits _timestamp, * and returns the average APR calculated across all the included * log entries. APR is multiplied by PERCENT_DIVISOR to retain precision. */ function averageAPRSince(uint256 _timestamp) external view returns (int256) { require(harvestLog.length >= 2, "need at least 2 log entries"); int256 runningAPRSum; int256 numLogsProcessed; for (uint256 i = harvestLog.length - 1; i > 0 && harvestLog[i].timestamp >= _timestamp; i--) { runningAPRSum += calculateAPRUsingLogs(i - 1, i); numLogsProcessed++; } return runningAPRSum / numLogsProcessed; } /** * @dev Traverses the harvest log backwards _n items, * and returns the average APR calculated across all the included * log entries. APR is multiplied by PERCENT_DIVISOR to retain precision. */ function averageAPRAcrossLastNHarvests(int256 _n) external view returns (int256) { require(harvestLog.length >= 2, "need at least 2 log entries"); int256 runningAPRSum; int256 numLogsProcessed; for (uint256 i = harvestLog.length - 1; i > 0 && numLogsProcessed < _n; i--) { runningAPRSum += calculateAPRUsingLogs(i - 1, i); numLogsProcessed++; } return runningAPRSum / numLogsProcessed; } function calculateAPRUsingLogs(uint256 _startIndex, uint256 _endIndex) public view returns (int256) { Harvest storage start = harvestLog[_startIndex]; Harvest storage end = harvestLog[_endIndex]; bool increasing = true; if (end.vaultSharePrice < start.vaultSharePrice) { increasing = false; } uint256 unsignedSharePriceChange; if (increasing) { unsignedSharePriceChange = end.vaultSharePrice - start.vaultSharePrice; } else { unsignedSharePriceChange = start.vaultSharePrice - end.vaultSharePrice; } uint256 unsignedPercentageChange = (unsignedSharePriceChange * 1e18) / start.vaultSharePrice; uint256 timeDifference = end.timestamp - start.timestamp; uint256 yearlyUnsignedPercentageChange = (unsignedPercentageChange * ONE_YEAR) / timeDifference; yearlyUnsignedPercentageChange /= 1e14; // restore basis points precision if (increasing) { return int256(yearlyUnsignedPercentageChange); } return -int256(yearlyUnsignedPercentageChange); } }
{ "metadata": { "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_lpToken","type":"address"},{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"address","name":"_vault","type":"address"},{"internalType":"address","name":"_treasury","type":"address"},{"internalType":"address","name":"_strategistRemitter","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newCallFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newTreasuryFee","type":"uint256"}],"name":"CallFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"harvester","type":"address"}],"name":"StratHarvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"TotalFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"BeetVault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"LPs","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ONE_YEAR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERCENT_DIVISOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STRATEGIST_MAX_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int256","name":"_n","type":"int256"}],"name":"averageAPRAcrossLastNHarvests","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"averageAPRSince","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balanceOfLpPair","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balanceOfPool","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"beetsPosition","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"beetsUnderlying","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_startIndex","type":"uint256"},{"internalType":"uint256","name":"_endIndex","type":"uint256"}],"name":"calculateAPRUsingLogs","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"callFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"depositsPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fBEETS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"harvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"harvestLog","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"vaultSharePrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"harvestLogCadence","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"harvestLogLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"harvestOn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_setting","type":"bool"}],"name":"harvestOnAction","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"isEmitting","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_n","type":"uint256"}],"name":"latestHarvestLogSlice","outputs":[{"components":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"vaultSharePrice","type":"uint256"}],"internalType":"struct ReaperAutoCompoundBeethoven_fBEETS.Harvest[]","name":"slice","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lpToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"masterChef","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":"panic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolID_bytes","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"retireStrat","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"route_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"secondReward","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"status","type":"bool"},{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"route","type":"bytes32"}],"name":"secondRewardInformation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"secondRewardRoute","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"secondRewardToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"securityFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_registry","type":"address"},{"internalType":"bytes32","name":"_id","type":"bytes32"},{"internalType":"address","name":"_delegate","type":"address"}],"name":"setDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_depositsPaused","type":"bool"}],"name":"setDepositsPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"strategistFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"strategistRemitter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"},{"internalType":"bytes32[]","name":"_routes","type":"bytes32[]"}],"name":"swapBribeToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_router","type":"address"},{"internalType":"address[]","name":"_path","type":"address[]"}],"name":"swapBribeTokenWithUniRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalUnderlyingTokens","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasuryFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"underlyingLP","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_callFee","type":"uint256"}],"name":"updateCallFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newCadenceInSeconds","type":"uint256"}],"name":"updateHarvestLogCadence","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"newID","type":"bytes32"}],"name":"updateRouteID","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"updateSecurityFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_strategistFee","type":"uint256"}],"name":"updateStrategistFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_totalFee","type":"uint256"}],"name":"updateTotalFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newTreasury","type":"address"}],"name":"updateTreasury","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wftm","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wftmPosition","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wftmRoute_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wftmUnderlying","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wrappedNative","type":"address"}],"name":"wrapNativeBribe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6080604052600380546001600160b01b031916758166994d9ebbe5829ec86bd81258149b87facfd300001790556006805463ffffffff191690556008805460ff19169055610e10600b556103e8600f556123286010556109c4601155600a6012556101c26013553480156200007357600080fd5b5060405162004db338038062004db38339810160408190526200009691620009df565b620000a133620003a9565b6000805460ff60a01b19169055600180546001600160a01b038088166001600160a01b03199283161790925560048681557fcde5a11a4acb4ee4c805352cec57e236bdbc38370002000000000000000000196005819055600d8054888616908516179055600c8054878616908516179055600e80549486169490931693909317909155604051631f29a8cd60e31b815260609260008051602062004d938339815191529263f94d4668926200015b92910190815260200190565b60006040518083038186803b1580156200017457600080fd5b505afa15801562000189573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620001b3919081019062000b35565b505080516001805460ff909216600160a01b0260ff60a01b19909216919091179055905060005b81518160ff161015620002e057818160ff1681518110620001ff57620001ff62000c10565b60209081029190910181015160ff831660009081526014909252604090912080546001600160a01b0319166001600160a01b0390921691821790557321be370d5312f44cb42ce377bc9b8a0cef1a4c8314156200027c576006805463ff0000001960ff8416610100021663ff00ff00199091161763010000001790555b60ff81166000908152601460205260409020546001600160a01b031673f24bcf4d1e507740041c9cfd2dddb29585adce1e1415620002cb576006805462ff00ff191660ff831617620100001790555b80620002d78162000c26565b915050620001da565b50620002eb620003f9565b600a6040518060400160405280428152602001866001600160a01b03166377c7b8fc6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200033857600080fd5b505afa1580156200034d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000373919062000c55565b90528154600181810184556000938452602093849020835160029093020191825592909101519101555062000d19945050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6200043b73cde5a11a4acb4ee4c805352cec57e236bdbc383773fcef8a994209d6916eb2c86cdd2afd60aa6f54b16000620005f9602090811b620021aa17901c565b6200047873f24bcf4d1e507740041c9cfd2dddb29585adce1e60008051602062004d938339815191526000620005f9602090811b620021aa17901c565b620004b57321be370d5312f44cb42ce377bc9b8a0cef1a4c8360008051602062004d938339815191526000620005f9602090811b620021aa17901c565b600354620004f69073fcef8a994209d6916eb2c86cdd2afd60aa6f54b1906201000090046001600160a01b03166000620005f9602090811b620021aa17901c565b6200053973cde5a11a4acb4ee4c805352cec57e236bdbc383773fcef8a994209d6916eb2c86cdd2afd60aa6f54b1600019620005f9602090811b620021aa17901c565b6200057773f24bcf4d1e507740041c9cfd2dddb29585adce1e60008051602062004d93833981519152600019620005f9602090811b620021aa17901c565b620005b57321be370d5312f44cb42ce377bc9b8a0cef1a4c8360008051602062004d93833981519152600019620005f9602090811b620021aa17901c565b600354620005f79073fcef8a994209d6916eb2c86cdd2afd60aa6f54b1906201000090046001600160a01b0316600019620005f9602090811b620021aa17901c565b565b801580620006875750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b1580156200064a57600080fd5b505afa1580156200065f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000685919062000c55565b155b620006ff5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e63650000000000000000000060648201526084015b60405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b17909152620007579185916200075c16565b505050565b6000620007b8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166200083a60201b62002301179092919060201c565b805190915015620007575780806020019051810190620007d9919062000c6f565b620007575760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401620006f6565b60606200084b848460008562000855565b90505b9392505050565b606082471015620008b85760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401620006f6565b843b620009085760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401620006f6565b600080866001600160a01b0316858760405162000926919062000cc6565b60006040518083038185875af1925050503d806000811462000965576040519150601f19603f3d011682016040523d82523d6000602084013e6200096a565b606091505b5090925090506200097d82828662000988565b979650505050505050565b60608315620009995750816200084e565b825115620009aa5782518084602001fd5b8160405162461bcd60e51b8152600401620006f6919062000ce4565b6001600160a01b0381168114620009dc57600080fd5b50565b600080600080600060a08688031215620009f857600080fd5b855162000a0581620009c6565b60208701516040880151919650945062000a1f81620009c6565b606087015190935062000a3281620009c6565b608087015190925062000a4581620009c6565b809150509295509295909350565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171562000a945762000a9462000a53565b604052919050565b60006001600160401b0382111562000ab85762000ab862000a53565b5060051b60200190565b600082601f83011262000ad457600080fd5b8151602062000aed62000ae78362000a9c565b62000a69565b82815260059290921b8401810191818101908684111562000b0d57600080fd5b8286015b8481101562000b2a578051835291830191830162000b11565b509695505050505050565b60008060006060848603121562000b4b57600080fd5b83516001600160401b038082111562000b6357600080fd5b818601915086601f83011262000b7857600080fd5b8151602062000b8b62000ae78362000a9c565b82815260059290921b8401810191818101908a84111562000bab57600080fd5b948201945b8386101562000bd657855162000bc681620009c6565b8252948201949082019062000bb0565b9189015191975090935050508082111562000bf057600080fd5b5062000bff8682870162000ac2565b925050604084015190509250925092565b634e487b7160e01b600052603260045260246000fd5b600060ff821660ff81141562000c4c57634e487b7160e01b600052601160045260246000fd5b60010192915050565b60006020828403121562000c6857600080fd5b5051919050565b60006020828403121562000c8257600080fd5b815180151581146200084e57600080fd5b60005b8381101562000cb057818101518382015260200162000c96565b8381111562000cc0576000848401525b50505050565b6000825162000cda81846020870162000c93565b9190910192915050565b602081526000825180602084015262000d0581604085016020870162000c93565b601f01601f19169190910160400192915050565b61406a8062000d296000396000f3fe6080604052600436106104095760003560e01c80638838d13a11610213578063d68e130211610123578063f4f45b46116100ab578063f91154531161007a578063f911545314610bfb578063fb61778714610c1b578063fbfa77cf14610c30578063fec94ad114610c50578063ff08b97d14610c6a57600080fd5b8063f4f45b4614610b77578063f587cde914610b99578063f7c618c114610bb3578063f88fb68914610bdb57600080fd5b8063edf2d5d2116100f2578063edf2d5d214610ab5578063f0f4809214610ad5578063f2fde38b14610b02578063f37ae32814610b22578063f4852a8114610b5757600080fd5b8063d68e130214610a4f578063ec4942da14610a65578063ec90b12214610a7f578063ecf173ff14610a9f57600080fd5b8063aaf8561a116101a6578063c8212ce211610175578063c8212ce2146109c4578063cc32d176146109e4578063ced0883e146109fa578063d0e30db014610a1a578063d32b960414610a2f57600080fd5b8063aaf8561a14610962578063bc063e1a14610983578063bdd3105814610999578063c2351cdd146109af57600080fd5b80638da5cb5b116101e25780638da5cb5b146108d357806390321e1a146108f1578063949c12c3146109075780639a111c371461093d57600080fd5b80638838d13a146108435780638888f9f6146108635780638954ffeb146108835780638cf55882146108b357600080fd5b80634967117111610319578063682274e3116102a157806372c95e561161027057806372c95e56146107b05780637330d4b8146107c65780637380fa3f146107e65780637f51bb1f1461080e5780638456cb591461082e57600080fd5b8063682274e31461073e5780636f680bcf1461075e578063715018a614610786578063722713f71461079b57600080fd5b80635fcbd285116102e85780635fcbd285146106a957806360da3e83146106c957806361591149146106e857806361d027b314610708578063635f91d01461072857600080fd5b80634967117114610622578063526e108014610642578063575a86b2146106585780635c975abb1461067e57600080fd5b80632ae3af4b1161039c5780633e6b35cb1161036b5780633e6b35cb1461059c5780633f4ba83a146105cd5780634641257d146105e25780634700d305146105f75780634870dd9a1461060c57600080fd5b80632ae3af4b1461053b5780632d6f4baa146105515780632e1a7d4d146105665780633e0dc34e1461058657600080fd5b806316d3bfbb116103d857806316d3bfbb146104b95780631c481e2d146104d15780631df4ccfc146104f15780631eec45921461050757600080fd5b806303b17808146104155780630463b7de146104375780630537524b14610457578063115880861461049657600080fd5b3661041057005b600080fd5b34801561042157600080fd5b50610435610430366004613804565b610c8b565b005b34801561044357600080fd5b50610435610452366004613840565b610d25565b34801561046357600080fd5b5061047960008051602061401583398151915281565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156104a257600080fd5b506104ab610d95565b60405190815260200161048d565b3480156104c557600080fd5b506104ab6301e1338081565b3480156104dd57600080fd5b506104356104ec366004613867565b610e28565b3480156104fd57600080fd5b506104ab60135481565b34801561051357600080fd5b506104ab7fcde5a11a4acb4ee4c805352cec57e236bdbc383700020000000000000000001981565b34801561054757600080fd5b506104ab60095481565b34801561055d57600080fd5b50600a546104ab565b34801561057257600080fd5b50610435610581366004613840565b610e6c565b34801561059257600080fd5b506104ab60045481565b3480156105a857600080fd5b506006546105bb90610100900460ff1681565b60405160ff909116815260200161048d565b3480156105d957600080fd5b506104356110b3565b3480156105ee57600080fd5b506104356110f7565b34801561060357600080fd5b50610435611101565b34801561061857600080fd5b506104ab61271081565b34801561062e57600080fd5b5061043561063d366004613884565b61119f565b34801561064e57600080fd5b506104ab60115481565b34801561066457600080fd5b50600354610479906201000090046001600160a01b031681565b34801561068a57600080fd5b50600054600160a01b900460ff165b604051901515815260200161048d565b3480156106b557600080fd5b50600154610479906001600160a01b031681565b3480156106d557600080fd5b5060035461069990610100900460ff1681565b3480156106f457600080fd5b50610435610703366004613840565b6112f6565b34801561071457600080fd5b50600c54610479906001600160a01b031681565b34801561073457600080fd5b506104ab60075481565b34801561074a57600080fd5b506104ab610759366004613840565b611365565b34801561076a57600080fd5b5061047973fcef8a994209d6916eb2c86cdd2afd60aa6f54b181565b34801561079257600080fd5b50610435611461565b3480156107a757600080fd5b506104ab611495565b3480156107bc57600080fd5b506104ab600b5481565b3480156107d257600080fd5b506104356107e13660046138eb565b6114b5565b3480156107f257600080fd5b5061047973cde5a11a4acb4ee4c805352cec57e236bdbc383781565b34801561081a57600080fd5b50610699610829366004613884565b61169b565b34801561083a57600080fd5b506104356116ea565b34801561084f57600080fd5b5061043561085e366004613957565b611724565b34801561086f57600080fd5b50600e54610479906001600160a01b031681565b34801561088f57600080fd5b5061069961089e3660046139aa565b60026020526000908152604090205460ff1681565b3480156108bf57600080fd5b506104ab6108ce3660046139cd565b611890565b3480156108df57600080fd5b506000546001600160a01b0316610479565b3480156108fd57600080fd5b506104ab600f5481565b34801561091357600080fd5b506104796109223660046139aa565b6014602052600090815260409020546001600160a01b031681565b34801561094957600080fd5b506008546104799061010090046001600160a01b031681565b34801561096e57600080fd5b506001546105bb90600160a01b900460ff1681565b34801561098f57600080fd5b506104ab6101f481565b3480156109a557600080fd5b506104ab60055481565b3480156109bb57600080fd5b506104ab6119c5565b3480156109d057600080fd5b506104356109df366004613840565b611a41565b3480156109f057600080fd5b506104ab60105481565b348015610a0657600080fd5b506006546106999062010000900460ff1681565b348015610a2657600080fd5b50610435611a70565b348015610a3b57600080fd5b50610699610a4a366004613840565b611ac8565b348015610a5b57600080fd5b506104ab60125481565b348015610a7157600080fd5b506003546106999060ff1681565b348015610a8b57600080fd5b50610435610a9a366004613840565b611b75565b348015610aab57600080fd5b506104ab61138881565b348015610ac157600080fd5b50610435610ad03660046139ef565b611ba4565b348015610ae157600080fd5b50610af5610af0366004613840565b611c86565b60405161048d9190613a2d565b348015610b0e57600080fd5b50610435610b1d366004613884565b611d8d565b348015610b2e57600080fd5b50610b42610b3d366004613840565b611e28565b6040805192835260208301919091520161048d565b348015610b6357600080fd5b506104ab610b72366004613840565b611e56565b348015610b8357600080fd5b50610479600080516020613ff583398151915281565b348015610ba557600080fd5b506006546105bb9060ff1681565b348015610bbf57600080fd5b5061047973f24bcf4d1e507740041c9cfd2dddb29585adce1e81565b348015610be757600080fd5b50610699610bf6366004613840565b611f14565b348015610c0757600080fd5b50610699610c16366004613867565b611f8e565b348015610c2757600080fd5b50610435611fd0565b348015610c3c57600080fd5b50600d54610479906001600160a01b031681565b348015610c5c57600080fd5b506008546106999060ff1681565b348015610c7657600080fd5b50600654610699906301000000900460ff1681565b6000546001600160a01b03163314610cbe5760405162461bcd60e51b8152600401610cb590613a7c565b60405180910390fd5b6040516317b0dca160e31b8152600481018390526001600160a01b03828116602483015284169063bd86e50890604401600060405180830381600087803b158015610d0857600080fd5b505af1158015610d1c573d6000803e3d6000fd5b50505050505050565b6000546001600160a01b03163314610d4f5760405162461bcd60e51b8152600401610cb590613a7c565b611388811115610d905760405162461bcd60e51b815260206004820152600c60248201526b08ccaca40a8dede4090d2ced60a31b6044820152606401610cb5565b601155565b600354600480546040516393f1a40b60e01b8152918201523060248201526000918291620100009091046001600160a01b0316906393f1a40b90604401604080518083038186803b158015610de957600080fd5b505afa158015610dfd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e219190613ab1565b5092915050565b6000546001600160a01b03163314610e525760405162461bcd60e51b8152600401610cb590613a7c565b600380549115156101000261ff0019909216919091179055565b60035460ff16151560011415610e8657610e86600061231a565b600d546001600160a01b03163314610ec95760405162461bcd60e51b8152602060048201526006602482015265085d985d5b1d60d21b6044820152606401610cb5565b6001546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b158015610f0d57600080fd5b505afa158015610f21573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f459190613ad5565b90508181101561105057600354600454620100009091046001600160a01b03169063d1abb90790610f76858561253c565b6040516001600160e01b031960e085901b16815260048101929092526024820152306044820152606401600060405180830381600087803b158015610fba57600080fd5b505af1158015610fce573d6000803e3d6000fd5b50506001546040516370a0823160e01b81523060048201526001600160a01b0390911692506370a08231915060240160206040518083038186803b15801561101557600080fd5b505afa158015611029573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061104d9190613ad5565b90505b8181111561105b5750805b600061107e6127106110786012548561254890919063ffffffff16565b90612554565b600d549091506110ae906001600160a01b031661109b848461253c565b6001546001600160a01b03169190612560565b505050565b6000546001600160a01b031633146110dd5760405162461bcd60e51b8152600401610cb590613a7c565b6110e5612590565b6110ed61262d565b6110f56127ab565b565b6110f5600061231a565b6000546001600160a01b0316331461112b5760405162461bcd60e51b8152600401610cb590613a7c565b6111336116ea565b600354600480546040516302f940c760e41b815291820152306024820152620100009091046001600160a01b031690632f940c7090604401600060405180830381600087803b15801561118557600080fd5b505af1158015611199573d6000803e3d6000fd5b50505050565b6000546001600160a01b031633146111c95760405162461bcd60e51b8152600401610cb590613a7c565b60008190506000479050816001600160a01b03166335052d6e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561120c57600080fd5b505afa158015611220573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112449190613ad5565b826001600160a01b031663d0e30db0836040518263ffffffff1660e01b81526004016020604051808303818588803b15801561127f57600080fd5b505af1158015611293573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906112b89190613ad5565b146110ae5760405162461bcd60e51b815260206004820152600e60248201526d3bb930b83834b7339032b93937b960911b6044820152606401610cb5565b6000546001600160a01b031633146113205760405162461bcd60e51b8152600401610cb590613a7c565b600a8111156113605760405162461bcd60e51b815260206004820152600c60248201526b0cccaca40e8dede40d0d2ced60a31b6044820152606401610cb5565b601255565b600a54600090600211156113bb5760405162461bcd60e51b815260206004820152601b60248201527f6e656564206174206c656173742032206c6f6720656e747269657300000000006044820152606401610cb5565b60008060006001600a805490506113d29190613b04565b90505b600081118015611409575084600a82815481106113f4576113f4613b1b565b90600052602060002090600202016000015410155b1561144e5761142261141c600183613b04565b82611890565b61142c9084613b31565b92508161143881613b72565b925050808061144690613b92565b9150506113d5565b506114598183613bbf565b949350505050565b6000546001600160a01b0316331461148b5760405162461bcd60e51b8152600401610cb590613a7c565b6110f560006128e1565b60006114b06114a2610d95565b6114aa6119c5565b90612931565b905090565b6000546001600160a01b031633146114df5760405162461bcd60e51b8152600401610cb590613a7c565b82158015906114ed57508281145b6115265760405162461bcd60e51b815260206004820152600a6024820152696261642061727261797360b01b6044820152606401610cb5565b60005b8381101561169057600061153e600186613b04565b821415611560575073f24bcf4d1e507740041c9cfd2dddb29585adce1e611594565b858561156d846001613bed565b81811061157c5761157c613b1b565b90506020020160208101906115919190613884565b90505b61167d8686848181106115a9576115a9613b1b565b90506020020160208101906115be9190613884565b828686868181106115d1576115d1613b1b565b905060200201358989878181106115ea576115ea613b1b565b90506020020160208101906115ff9190613884565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a082319060240160206040518083038186803b15801561164057600080fd5b505afa158015611654573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116789190613ad5565b61293d565b508061168881613c05565b915050611529565b50611199600161231a565b600080546001600160a01b031633146116c65760405162461bcd60e51b8152600401610cb590613a7c565b50600c80546001600160a01b0319166001600160a01b03831617905560015b919050565b6000546001600160a01b031633146117145760405162461bcd60e51b8152600401610cb590613a7c565b61171c612acf565b6110f5612b34565b6000546001600160a01b0316331461174e5760405162461bcd60e51b8152600401610cb590613a7c565b60008282600081811061176357611763613b1b565b90506020020160208101906117789190613884565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038316906370a082319060240160206040518083038186803b1580156117bd57600080fd5b505afa1580156117d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f59190613ad5565b905061180b6001600160a01b0383168683612bf1565b6001600160a01b038516635c11d79582600087873061182c42610258613bed565b6040518763ffffffff1660e01b815260040161184d96959493929190613c19565b600060405180830381600087803b15801561186757600080fd5b505af115801561187b573d6000803e3d6000fd5b50505050611889600161231a565b5050505050565b600080600a84815481106118a6576118a6613b1b565b906000526020600020906002020190506000600a84815481106118cb576118cb613b1b565b906000526020600020906002020190506000600190508260010154826001015410156118f5575060005b6000811561191857836001015483600101546119119190613b04565b905061192f565b8260010154846001015461192c9190613b04565b90505b600184015460009061194983670de0b6b3a7640000613c8a565b6119539190613ca9565b855485549192506000916119679190613b04565b905060008161197a6301e1338085613c8a565b6119849190613ca9565b9050611996655af3107a400082613ca9565b905084156119ac5796506119bf95505050505050565b6119b581613cbd565b9750505050505050505b92915050565b6001546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b158015611a0957600080fd5b505afa158015611a1d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114b09190613ad5565b6000546001600160a01b03163314611a6b5760405162461bcd60e51b8152600401610cb590613a7c565b600755565b600354610100900460ff16156110ed5760405162461bcd60e51b815260206004820152601b60248201527f63616e6e6f74206465706f73697420617420746869732074696d6500000000006044820152606401610cb5565b600080546001600160a01b03163314611af35760405162461bcd60e51b8152600401610cb590613a7c565b6101f4821115611b345760405162461bcd60e51b815260206004820152600c60248201526b08ccaca40a8dede4090d2ced60a31b6044820152606401610cb5565b60138290556040518281527f2e59d502792bca3d730c472cd3acfbc16d0f9fe6ce0cddbdf0f80830251dfaca906020015b60405180910390a1506001919050565b6000546001600160a01b03163314611b9f5760405162461bcd60e51b8152600401610cb590613a7c565b600b55565b6000546001600160a01b03163314611bce5760405162461bcd60e51b8152600401610cb590613a7c565b6001600160a01b03821673f24bcf4d1e507740041c9cfd2dddb29585adce1e1415611c475760405162461bcd60e51b8152602060048201526024808201527f726577617264546f6b656e20697320616c7265616479206163636f756e746564604482015263103337b960e11b6064820152608401610cb5565b600880546001600160a01b0390931661010002610100600160a81b0319941515949094166001600160a81b031990931692909217929092179055600955565b60608167ffffffffffffffff811115611ca157611ca1613cda565b604051908082528060200260200182016040528015611ce657816020015b6040805180820190915260008082526020820152815260200190600190039081611cbf5790505b50905060008083600a80549050611cfd9190613b04565b90505b600a54811015611d8657600a8181548110611d1d57611d1d613b1b565b906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050838380611d5690613c05565b945081518110611d6857611d68613b1b565b60200260200101819052508080611d7e90613c05565b915050611d00565b5050919050565b6000546001600160a01b03163314611db75760405162461bcd60e51b8152600401610cb590613a7c565b6001600160a01b038116611e1c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610cb5565b611e25816128e1565b50565b600a8181548110611e3857600080fd5b60009182526020909120600290910201805460019091015490915082565b600a5460009060021115611eac5760405162461bcd60e51b815260206004820152601b60248201527f6e656564206174206c656173742032206c6f6720656e747269657300000000006044820152606401610cb5565b60008060006001600a80549050611ec39190613b04565b90505b600081118015611ed557508482125b1561144e57611ee861141c600183613b04565b611ef29084613b31565b925081611efe81613b72565b9250508080611f0c90613b92565b915050611ec6565b600080546001600160a01b03163314611f3f5760405162461bcd60e51b8152600401610cb590613a7c565b600f829055611f506127108361253c565b6010819055600f546040517f06a730aa61ec47f8cc95582be032daaf0ec4cb816c24b9c07b574ea41821048b92611b65928252602082015260400190565b600080546001600160a01b03163314611fb95760405162461bcd60e51b8152600401610cb590613a7c565b506003805460ff1916911515919091179055600190565b600d546001600160a01b031633146120135760405162461bcd60e51b8152602060048201526006602482015265085d985d5b1d60d21b6044820152606401610cb5565b600360029054906101000a90046001600160a01b03166001600160a01b031663d1abb907600454612042610d95565b6040516001600160e01b031960e085901b16815260048101929092526024820152306044820152606401600060405180830381600087803b15801561208657600080fd5b505af115801561209a573d6000803e3d6000fd5b50506001546040516370a0823160e01b8152306004820152600093506001600160a01b0390911691506370a082319060240160206040518083038186803b1580156120e457600080fd5b505afa1580156120f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061211c9190613ad5565b600154600d5460405163a9059cbb60e01b81526001600160a01b03918216600482015260248101849052929350169063a9059cbb90604401602060405180830381600087803b15801561216e57600080fd5b505af1158015612182573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121a69190613cf0565b5050565b8015806122335750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b1580156121f957600080fd5b505afa15801561220d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122319190613ad5565b155b61229e5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610cb5565b6040516001600160a01b0383166024820152604481018290526110ae90849063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612cb2565b60606123108484600085612d84565b90505b9392505050565b600054600160a01b900460ff16156123445760405162461bcd60e51b8152600401610cb590613d0d565b60035460048054604051630c7e663b60e11b815291820152306024820152620100009091046001600160a01b0316906318fccc7690604401600060405180830381600087803b15801561239657600080fd5b505af11580156123aa573d6000803e3d6000fd5b505050506123b781612eac565b60085460ff16156123e0576008546009546123e09161010090046001600160a01b031690613185565b6006546124059073f24bcf4d1e507740041c9cfd2dddb29585adce1e9060ff16613438565b61240d6136f4565b6124156127ab565b600b54600a805461242890600190613b04565b8154811061243857612438613b1b565b9060005260206000209060020201600001546124549190613bed565b421061250e57604080518082018252428152600d548251631df1ee3f60e21b81529251600a936020808501936001600160a01b0316926377c7b8fc926004808201939291829003018186803b1580156124ac57600080fd5b505afa1580156124c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124e49190613ad5565b90528154600181810184556000938452602093849020835160029093020191825592909101519101555b60405133907f577a37fdb49a88d66684922c6f913df5239b4f214b2b97c53ef8e3bbb2034cb590600090a250565b60006123138284613b04565b60006123138284613c8a565b60006123138284613ca9565b6040516001600160a01b0383166024820152604481018290526110ae90849063a9059cbb60e01b906064016122ca565b600054600160a01b900460ff166125e05760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610cb5565b6000805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b61266173cde5a11a4acb4ee4c805352cec57e236bdbc383773fcef8a994209d6916eb2c86cdd2afd60aa6f54b160006121aa565b61268f73f24bcf4d1e507740041c9cfd2dddb29585adce1e60008051602061401583398151915260006121aa565b6126b7600080516020613ff583398151915260008051602061401583398151915260006121aa565b6003546126ea9073fcef8a994209d6916eb2c86cdd2afd60aa6f54b1906201000090046001600160a01b031660006121aa565b61271f73cde5a11a4acb4ee4c805352cec57e236bdbc383773fcef8a994209d6916eb2c86cdd2afd60aa6f54b16000196121aa565b61274e73f24bcf4d1e507740041c9cfd2dddb29585adce1e6000805160206140158339815191526000196121aa565b612777600080516020613ff58339815191526000805160206140158339815191526000196121aa565b6003546110f59073fcef8a994209d6916eb2c86cdd2afd60aa6f54b1906201000090046001600160a01b03166000196121aa565b600054600160a01b900460ff16156127d55760405162461bcd60e51b8152600401610cb590613d0d565b60035460ff161515600114156127ef576127ef600061231a565b6001546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561283357600080fd5b505afa158015612847573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061286b9190613ad5565b90508015611e255760035460048054604051638dbdbe6d60e01b81529182015260248101839052306044820152620100009091046001600160a01b031690638dbdbe6d906064015b600060405180830381600087803b1580156128cd57600080fd5b505af1158015611889573d6000803e3d6000fd5b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006123138284613bed565b6129896040805160c0810190915260008082526020820190815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160008152602001606081525090565b828152600060208083018290526001600160a01b03878116604080860182905291881660608087019190915260808087018890528351808601879052845180820387018152908501855260a08801528351908101845293840185905283018490523080845291830191909152612a0e90600080516020614015833981519152846121aa565b612a306001600160a01b038816600080516020614015833981519152866121aa565b6000805160206140158339815191526352bbbe2984836001612a5442610258613bed565b6040518563ffffffff1660e01b8152600401612a739493929190613da5565b602060405180830381600087803b158015612a8d57600080fd5b505af1158015612aa1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ac59190613ad5565b5050505050505050565b600054600160a01b900460ff1615612af95760405162461bcd60e51b8152600401610cb590613d0d565b6000805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586126103390565b612b6873cde5a11a4acb4ee4c805352cec57e236bdbc383773fcef8a994209d6916eb2c86cdd2afd60aa6f54b160006121aa565b612b9673f24bcf4d1e507740041c9cfd2dddb29585adce1e60008051602061401583398151915260006121aa565b612bbe600080516020613ff583398151915260008051602061401583398151915260006121aa565b6003546110f59073fcef8a994209d6916eb2c86cdd2afd60aa6f54b1906201000090046001600160a01b031660006121aa565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e9060440160206040518083038186803b158015612c3d57600080fd5b505afa158015612c51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c759190613ad5565b612c7f9190613bed565b6040516001600160a01b03851660248201526044810182905290915061119990859063095ea7b360e01b906064016122ca565b6000612d07826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166123019092919063ffffffff16565b8051909150156110ae5780806020019051810190612d259190613cf0565b6110ae5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610cb5565b606082471015612de55760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610cb5565b843b612e335760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610cb5565b600080866001600160a01b03168587604051612e4f9190613e67565b60006040518083038185875af1925050503d8060008114612e8c576040519150601f19603f3d011682016040523d82523d6000602084013e612e91565b606091505b5091509150612ea18282866137b4565b979650505050505050565b6040516370a0823160e01b815230600482015260009073f24bcf4d1e507740041c9cfd2dddb29585adce1e906370a082319060240160206040518083038186803b158015612ef957600080fd5b505afa158015612f0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f319190613ad5565b6040516370a0823160e01b8152306004820152909150600090600080516020613ff5833981519152906370a082319060240160206040518083038186803b158015612f7b57600080fd5b505afa158015612f8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fb39190613ad5565b9050600080612fd36127106110786013548761254890919063ffffffff16565b915061302373f24bcf4d1e507740041c9cfd2dddb29585adce1e600080516020613ff58339815191527fcde5a11a4acb4ee4c805352cec57e236bdbc38370002000000000000000000198561293d565b6040516370a0823160e01b81523060048201526130ac908490600080516020613ff5833981519152906370a08231906024015b60206040518083038186803b15801561306e57600080fd5b505afa158015613082573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130a69190613ad5565b9061253c565b905060006130cb612710611078600f548561254890919063ffffffff16565b90506130e6600080516020613ff58339815191523383612560565b60006131036127106110786010548661254890919063ffffffff16565b9050861561315f5760006131286127106110786011548561254890919063ffffffff16565b9050613134828261253c565b600e5490925061315d90600080516020613ff5833981519152906001600160a01b031683612560565b505b600c54610d1c90600080516020613ff5833981519152906001600160a01b031683612560565b6040516370a0823160e01b8152306004820152600090600080516020613ff5833981519152906370a082319060240160206040518083038186803b1580156131cc57600080fd5b505afa1580156131e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132049190613ad5565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038516906370a082319060240160206040518083038186803b15801561324957600080fd5b505afa15801561325d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132819190613ad5565b905061329d84600080516020613ff5833981519152858461293d565b6013546040516370a0823160e01b81523060048201526000916132ec9161271091611078916132e6908890600080516020613ff5833981519152906370a0823190602401613056565b90612548565b9050600061330b612710611078600f548561254890919063ffffffff16565b9050613326600080516020613ff58339815191523383612560565b60006133436127106110786010548661254890919063ffffffff16565b600c5490915061336c90600080516020613ff5833981519152906001600160a01b031683612560565b6040516370a0823160e01b8152306004820152600080516020613ff5833981519152906370a082319060240160206040518083038186803b1580156133b057600080fd5b505afa1580156133c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133e89190613ad5565b9450610d1c600080516020613ff583398151915273f24bcf4d1e507740041c9cfd2dddb29585adce1e7fcde5a11a4acb4ee4c805352cec57e236bdbc38370002000000000000000000198861293d565b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a082319060240160206040518083038186803b15801561347a57600080fd5b505afa15801561348e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134b29190613ad5565b90506134d76001600160a01b03841660008051602061401583398151915260006121aa565b6134f96001600160a01b038416600080516020614015833981519152836121aa565b60018054600090600160a01b900460ff1667ffffffffffffffff81111561352257613522613cda565b60405190808252806020026020018201604052801561354b578160200160208202803683370190505b50905082818560ff168151811061356457613564613b1b565b602090810291909101015260018054600090600160a01b900460ff1667ffffffffffffffff81111561359857613598613cda565b6040519080825280602002602001820160405280156135c1578160200160208202803683370190505b50905060005b60015460ff600160a01b9091048116908216101561363a5760ff811660008181526014602052604090205483516001600160a01b03909116918491811061361057613610613b1b565b6001600160a01b03909216602092830291909101909101528061363281613e83565b9150506135c7565b50600084848460405160200161365293929190613ede565b60408051808303601f190181526080830182526000606084015284835260208301879052828201819052600554915163172b958560e31b81529093506000805160206140158339815191529163b95cac28916136b79190309081908790600401613f17565b600060405180830381600087803b1580156136d157600080fd5b505af11580156136e5573d6000803e3d6000fd5b50505050505050505050505050565b6040516370a0823160e01b815230600482015260009073cde5a11a4acb4ee4c805352cec57e236bdbc3837906370a082319060240160206040518083038186803b15801561374157600080fd5b505afa158015613755573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137799190613ad5565b604051632967cf8360e21b81526004810182905290915073fcef8a994209d6916eb2c86cdd2afd60aa6f54b19063a59f3e0c906024016128b3565b606083156137c3575081612313565b8251156137d35782518084602001fd5b8160405162461bcd60e51b8152600401610cb59190613fe1565b80356001600160a01b03811681146116e557600080fd5b60008060006060848603121561381957600080fd5b613822846137ed565b925060208401359150613837604085016137ed565b90509250925092565b60006020828403121561385257600080fd5b5035919050565b8015158114611e2557600080fd5b60006020828403121561387957600080fd5b813561231381613859565b60006020828403121561389657600080fd5b612313826137ed565b60008083601f8401126138b157600080fd5b50813567ffffffffffffffff8111156138c957600080fd5b6020830191508360208260051b85010111156138e457600080fd5b9250929050565b6000806000806040858703121561390157600080fd5b843567ffffffffffffffff8082111561391957600080fd5b6139258883890161389f565b9096509450602087013591508082111561393e57600080fd5b5061394b8782880161389f565b95989497509550505050565b60008060006040848603121561396c57600080fd5b613975846137ed565b9250602084013567ffffffffffffffff81111561399157600080fd5b61399d8682870161389f565b9497909650939450505050565b6000602082840312156139bc57600080fd5b813560ff8116811461231357600080fd5b600080604083850312156139e057600080fd5b50508035926020909101359150565b600080600060608486031215613a0457600080fd5b8335613a0f81613859565b9250613a1d602085016137ed565b9150604084013590509250925092565b602080825282518282018190526000919060409081850190868401855b82811015613a6f57815180518552860151868501529284019290850190600101613a4a565b5091979650505050505050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60008060408385031215613ac457600080fd5b505080516020909101519092909150565b600060208284031215613ae757600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600082821015613b1657613b16613aee565b500390565b634e487b7160e01b600052603260045260246000fd5b600080821280156001600160ff1b0384900385131615613b5357613b53613aee565b600160ff1b8390038412811615613b6c57613b6c613aee565b50500190565b60006001600160ff1b03821415613b8b57613b8b613aee565b5060010190565b600081613ba157613ba1613aee565b506000190190565b634e487b7160e01b600052601260045260246000fd5b600082613bce57613bce613ba9565b600160ff1b821460001984141615613be857613be8613aee565b500590565b60008219821115613c0057613c00613aee565b500190565b6000600019821415613b8b57613b8b613aee565b868152602080820187905260a0604083018190528201859052600090869060c08401835b88811015613c69576001600160a01b03613c56856137ed565b1682529282019290820190600101613c3d565b506001600160a01b0396909616606085015250505060800152949350505050565b6000816000190483118215151615613ca457613ca4613aee565b500290565b600082613cb857613cb8613ba9565b500490565b6000600160ff1b821415613cd357613cd3613aee565b5060000390565b634e487b7160e01b600052604160045260246000fd5b600060208284031215613d0257600080fd5b815161231381613859565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b634e487b7160e01b600052602160045260246000fd5b60005b83811015613d68578181015183820152602001613d50565b838111156111995750506000910152565b60008151808452613d91816020860160208601613d4d565b601f01601f19169290920160200192915050565b60e08152845160e08201526000602086015160028110613dc757613dc7613d37565b61010083015260408601516001600160a01b03908116610120840152606087015116610140830152608086015161016083015260a086015160c0610180840152613e156101a0840182613d79565b915050613e55602083018680516001600160a01b039081168352602080830151151590840152604080830151909116908301526060908101511515910152565b60a082019390935260c0015292915050565b60008251613e79818460208701613d4d565b9190910192915050565b600060ff821660ff811415613e9a57613e9a613aee565b60010192915050565b600081518084526020808501945080840160005b83811015613ed357815187529582019590820190600101613eb7565b509495945050505050565b600060048510613ef057613ef0613d37565b84825260606020830152613f076060830185613ea3565b9050826040830152949350505050565b8481526000602060018060a01b038087168285015280861660408501526080606085015261010084018551608080870152818151808452610120880191508583019350600092505b80831015613f8157835185168252928501926001929092019190850190613f5f565b50848801519450607f199350838782030160a0880152613fa18186613ea3565b94505050506040850151818584030160c0860152613fbf8382613d79565b925050506060840151613fd660e085018215159052565b509695505050505050565b6020815260006123136020830184613d7956fe00000000000000000000000021be370d5312f44cb42ce377bc9b8a0cef1a4c8300000000000000000000000020dd72ed959b6147912c2e529f0a0c651c33c9cea264697066735822122017c261cafae263a4586b1edaf080b482e7b68d49dec4e07e1ad79bea5073248764736f6c6343000809003300000000000000000000000020dd72ed959b6147912c2e529f0a0c651c33c9ce000000000000000000000000fcef8a994209d6916eb2c86cdd2afd60aa6f54b10000000000000000000000000000000000000000000000000000000000000016000000000000000000000000fb8dacdb058e84131d9c4a4bcd18a4f5704b48560000000000000000000000000e7c5313e9bb80b654734d9b7ab1fb01468dee3b00000000000000000000000063cbd4134c2253041f370472c130e92dae4ff174
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000fcef8a994209d6916eb2c86cdd2afd60aa6f54b10000000000000000000000000000000000000000000000000000000000000016000000000000000000000000fb8dacdb058e84131d9c4a4bcd18a4f5704b48560000000000000000000000000e7c5313e9bb80b654734d9b7ab1fb01468dee3b00000000000000000000000063cbd4134c2253041f370472c130e92dae4ff174
-----Decoded View---------------
Arg [0] : _lpToken (address): 0xfcef8a994209d6916eb2c86cdd2afd60aa6f54b1
Arg [1] : _poolId (uint256): 22
Arg [2] : _vault (address): 0xfb8dacdb058e84131d9c4a4bcd18a4f5704b4856
Arg [3] : _treasury (address): 0x0e7c5313e9bb80b654734d9b7ab1fb01468dee3b
Arg [4] : _strategistRemitter (address): 0x63cbd4134c2253041f370472c130e92dae4ff174
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000fcef8a994209d6916eb2c86cdd2afd60aa6f54b1
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000016
Arg [2] : 000000000000000000000000fb8dacdb058e84131d9c4a4bcd18a4f5704b4856
Arg [3] : 0000000000000000000000000e7c5313e9bb80b654734d9b7ab1fb01468dee3b
Arg [4] : 00000000000000000000000063cbd4134c2253041f370472c130e92dae4ff174
Deployed ByteCode Sourcemap
86090:22931:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;103835:164;;;;;;;;;;-1:-1:-1;103835:164:0;;;;;:::i;:::-;;:::i;:::-;;101036:186;;;;;;;;;;-1:-1:-1;101036:186:0;;;;;:::i;:::-;;:::i;86953:87::-;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;86953:87:0;;;;;-1:-1:-1;;;;;874:32:1;;;856:51;;844:2;829:18;86953:87:0;;;;;;;;98653:172;;;;;;;;;;;;;:::i;:::-;;;1064:25:1;;;1052:2;1037:18;98653:172:0;918:177:1;88132:43:0;;;;;;;;;;;;88167:8;88132:43;;103712:117;;;;;;;;;;-1:-1:-1;103712:117:0;;;;;:::i;:::-;;:::i;89655:26::-;;;;;;;;;;;;;;;;87736:105;;;;;;;;;;-1:-1:-1;87736:105:0;87775:66;87736:105;;87923:32;;;;;;;;;;;;;;;;105942:101;;;;;;;;;;-1:-1:-1;106019:10:0;:17;105942:101;;92776:587;;;;;;;;;;-1:-1:-1;92776:587:0;;;;;:::i;:::-;;:::i;87497:18::-;;;;;;;;;;;;;;;;87591:29;;;;;;;;;;-1:-1:-1;87591:29:0;;;;;;;;;;;;;;1823:4:1;1811:17;;;1793:36;;1781:2;1766:18;87591:29:0;1651:184:1;99754:114:0;;;;;;;;;;;;;:::i;93369:60::-;;;;;;;;;;;;;:::i;99432:132::-;;;;;;;;;;;;;:::i;89782:45::-;;;;;;;;;;;;89822:5;89782:45;;105308:285;;;;;;;;;;-1:-1:-1;105308:285:0;;;;;:::i;:::-;;:::i;89580:35::-;;;;;;;;;;;;;;;;87412:79;;;;;;;;;;-1:-1:-1;87412:79:0;;;;;;;-1:-1:-1;;;;;87412:79:0;;;37725:84;;;;;;;;;;-1:-1:-1;37772:4:0;37795:7;-1:-1:-1;;;37795:7:0;;;;37725:84;;;2292:14:1;;2285:22;2267:41;;2255:2;2240:18;37725:84:0;2127:187:1;87046:22:0;;;;;;;;;;-1:-1:-1;87046:22:0;;;;-1:-1:-1;;;;;87046:22:0;;;87197:34;;;;;;;;;;-1:-1:-1;87197:34:0;;;;;;;;;;;103397:140;;;;;;;;;;-1:-1:-1;103397:140:0;;;;;:::i;:::-;;:::i;88353:23::-;;;;;;;;;;-1:-1:-1;88353:23:0;;;;-1:-1:-1;;;;;88353:23:0;;;87707;;;;;;;;;;;;;;;;106708:477;;;;;;;;;;-1:-1:-1;106708:477:0;;;;;:::i;:::-;;:::i;86754:84::-;;;;;;;;;;;;86795:42;86754:84;;2526:101;;;;;;;;;;;;;:::i;98220:113::-;;;;;;;;;;;;;:::i;88084:42::-;;;;;;;;;;;;;;;;104092:601;;;;;;;;;;-1:-1:-1;104092:601:0;;;;;:::i;:::-;;:::i;86658:90::-;;;;;;;;;;;;86705:42;86658:90;;101913:135;;;;;;;;;;-1:-1:-1;101913:135:0;;;;;:::i;:::-;;:::i;99616:84::-;;;;;;;;;;;;;:::i;104772:530::-;;;;;;;;;;-1:-1:-1;104772:530:0;;;;;:::i;:::-;;:::i;88408:33::-;;;;;;;;;;-1:-1:-1;88408:33:0;;;;-1:-1:-1;;;;;88408:33:0;;;87116:40;;;;;;;;;;-1:-1:-1;87116:40:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;107895:1124;;;;;;;;;;-1:-1:-1;107895:1124:0;;;;;:::i;:::-;;:::i;1894:85::-;;;;;;;;;;-1:-1:-1;1940:7:0;1966:6;-1:-1:-1;;;;;1966:6:0;1894:85;;89512:26;;;;;;;;;;;;;;;;90186:37;;;;;;;;;;-1:-1:-1;90186:37:0;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;90186:37:0;;;87885:32;;;;;;;;;;-1:-1:-1;87885:32:0;;;;;;;-1:-1:-1;;;;;87885:32:0;;;87075:34;;;;;;;;;;-1:-1:-1;87075:34:0;;;;-1:-1:-1;;;87075:34:0;;;;;;89687;;;;;;;;;;;;89718:3;89687:34;;87521:27;;;;;;;;;;;;;;;;98420:121;;;;;;;;;;;;;:::i;101817:90::-;;;;;;;;;;-1:-1:-1;101817:90:0;;;;;:::i;:::-;;:::i;89544:30::-;;;;;;;;;;;;;;;;87626:35;;;;;;;;;;-1:-1:-1;87626:35:0;;;;;;;;;;;92197:120;;;;;;;;;;;;;:::i;100725:219::-;;;;;;;;;;-1:-1:-1;100725:219:0;;;;;:::i;:::-;;:::i;89621:28::-;;;;;;;;;;;;;;;;87162:29;;;;;;;;;;-1:-1:-1;87162:29:0;;;;;;;;105797:139;;;;;;;;;;-1:-1:-1;105797:139:0;;;;;:::i;:::-;;:::i;89727:49::-;;;;;;;;;;;;89772:4;89727:49;;103109:282;;;;;;;;;;-1:-1:-1;103109:282:0;;;;;:::i;:::-;;:::i;106147:307::-;;;;;;;;;;-1:-1:-1;106147:307:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;2776:198::-;;;;;;;;;;-1:-1:-1;2776:198:0;;;;;:::i;:::-;;:::i;88051:27::-;;;;;;;;;;-1:-1:-1;88051:27:0;;;;;:::i;:::-;;:::i;:::-;;;;6232:25:1;;;6288:2;6273:18;;6266:34;;;;6205:18;88051:27:0;6058:248:1;107423:466:0;;;;;;;;;;-1:-1:-1;107423:466:0;;;;;:::i;:::-;;:::i;86570:82::-;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;86570:82:0;;87555:30;;;;;;;;;;-1:-1:-1;87555:30:0;;;;;;;;86844:89;;;;;;;;;;;;86890:42;86844:89;;101330:223;;;;;;;;;;-1:-1:-1;101330:223:0;;;;;:::i;:::-;;:::i;101559:131::-;;;;;;;;;;-1:-1:-1;101559:131:0;;;;;:::i;:::-;;:::i;99016:301::-;;;;;;;;;;;;;:::i;88382:20::-;;;;;;;;;;-1:-1:-1;88382:20:0;;;;-1:-1:-1;;;;;88382:20:0;;;87847:32;;;;;;;;;;-1:-1:-1;87847:32:0;;;;;;;;87667:34;;;;;;;;;;-1:-1:-1;87667:34:0;;;;;;;;;;;103835:164;1940:7;1966:6;-1:-1:-1;;;;;1966:6:0;797:10;2106:23;2098:68;;;;-1:-1:-1;;;2098:68:0;;;;;;;:::i;:::-;;;;;;;;;103936:56:::1;::::0;-1:-1:-1;;;103936:56:0;;::::1;::::0;::::1;7030:25:1::0;;;-1:-1:-1;;;;;7091:32:1;;;7071:18;;;7064:60;103936:40:0;::::1;::::0;::::1;::::0;7003:18:1;;103936:56:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;103835:164:::0;;;:::o;101036:186::-;1940:7;1966:6;-1:-1:-1;;;;;1966:6:0;797:10;2106:23;2098:68;;;;-1:-1:-1;;;2098:68:0;;;;;;;:::i;:::-;89772:4:::1;101124:14;:36;;101116:61;;;::::0;-1:-1:-1;;;101116:61:0;;7337:2:1;101116:61:0::1;::::0;::::1;7319:21:1::0;7376:2;7356:18;;;7349:30;-1:-1:-1;;;7395:18:1;;;7388:42;7447:18;;101116:61:0::1;7135:336:1::0;101116:61:0::1;101185:13;:30:::0;101036:186::o;98653:172::-;98751:10;;98772:6;;;98739:55;;-1:-1:-1;;;98739:55:0;;;;;7030:25:1;98788:4:0;7071:18:1;;;7064:60;98699:7:0;;;;98751:10;;;;-1:-1:-1;;;;;98751:10:0;;98739:32;;7003:18:1;;98739:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;98718:76:0;98653:172;-1:-1:-1;;98653:172:0:o;103712:117::-;1940:7;1966:6;-1:-1:-1;;;;;1966:6:0;797:10;2106:23;2098:68;;;;-1:-1:-1;;;2098:68:0;;;;;;;:::i;:::-;103790:14:::1;:32:::0;;;::::1;;;;-1:-1:-1::0;;103790:32:0;;::::1;::::0;;;::::1;::::0;;103712:117::o;92776:587::-;101736:9;;;;:17;;:9;:17;101732:62;;;101768:15;101777:5;101768:8;:15::i;:::-;92863:5:::1;::::0;-1:-1:-1;;;;;92863:5:0::1;92849:10;:19;92841:38;;;::::0;-1:-1:-1;;;92841:38:0;;8207:2:1;92841:38:0::1;::::0;::::1;8189:21:1::0;8246:1;8226:18;;;8219:29;-1:-1:-1;;;8264:18:1;;;8257:36;8310:18;;92841:38:0::1;8005:329:1::0;92841:38:0::1;92913:7;::::0;92906:40:::1;::::0;-1:-1:-1;;;92906:40:0;;92940:4:::1;92906:40;::::0;::::1;856:51:1::0;92888:15:0::1;::::0;-1:-1:-1;;;;;92913:7:0::1;::::0;92906:25:::1;::::0;829:18:1;;92906:40:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;92888:58;;92969:7;92959;:17;92955:191;;;93002:10;::::0;93033:6:::1;::::0;93002:10;;;::::1;-1:-1:-1::0;;;;;93002:10:0::1;::::0;92988:44:::1;::::0;93041:20:::1;:7:::0;93053;93041:11:::1;:20::i;:::-;92988:89;::::0;-1:-1:-1;;;;;;92988:89:0::1;::::0;;;;;;::::1;::::0;::::1;8730:25:1::0;;;;8771:18;;;8764:34;93071:4:0::1;8814:18:1::0;;;8807:60;8703:18;;92988:89:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;93104:7:0::1;::::0;93097:40:::1;::::0;-1:-1:-1;;;93097:40:0;;93131:4:::1;93097:40;::::0;::::1;856:51:1::0;-1:-1:-1;;;;;93104:7:0;;::::1;::::0;-1:-1:-1;93097:25:0::1;::::0;-1:-1:-1;829:18:1;;93097:40:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;93087:50;;92955:191;93168:7;93158;:17;93154:59;;;-1:-1:-1::0;93197:7:0;93154:59:::1;93220:19;93242:45;89822:5;93242:24;93254:11;;93242:7;:11;;:24;;;;:::i;:::-;:28:::0;::::1;:45::i;:::-;93324:5;::::0;93220:67;;-1:-1:-1;93295:61:0::1;::::0;-1:-1:-1;;;;;93324:5:0::1;93331:24;:7:::0;93220:67;93331:11:::1;:24::i;:::-;93302:7;::::0;-1:-1:-1;;;;;93302:7:0::1;::::0;93295:61;:28:::1;:61::i;:::-;92835:528;;92776:587:::0;:::o;99754:114::-;1940:7;1966:6;-1:-1:-1;;;;;1966:6:0;797:10;2106:23;2098:68;;;;-1:-1:-1;;;2098:68:0;;;;;;;:::i;:::-;99802:10:::1;:8;:10::i;:::-;99823:17;:15;:17::i;:::-;99851:10;:8;:10::i;:::-;99754:114::o:0;93369:60::-;93407:15;93416:5;93407:8;:15::i;99432:132::-;1940:7;1966:6;-1:-1:-1;;;;;1966:6:0;797:10;2106:23;2098:68;;;;-1:-1:-1;;;2098:68:0;;;;;;;:::i;:::-;99476:7:::1;:5;:7::i;:::-;99505:10;::::0;99535:6:::1;::::0;;99493:64:::1;::::0;-1:-1:-1;;;99493:64:0;;;;::::1;7030:25:1::0;99551:4:0::1;7071:18:1::0;;;7064:60;99505:10:0;;;::::1;-1:-1:-1::0;;;;;99505:10:0::1;::::0;99493:41:::1;::::0;7003:18:1;;99493:64:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;99432:132::o:0;105308:285::-;1940:7;1966:6;-1:-1:-1;;;;;1966:6:0;797:10;2106:23;2098:68;;;;-1:-1:-1;;;2098:68:0;;;;;;;:::i;:::-;105386:22:::1;105426:14;105386:55;;105451:15;105469:21;105451:39;;105545:7;-1:-1:-1::0;;;;;105545:20:0::1;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;105508:7;-1:-1:-1::0;;;;;105508:15:0::1;;105531:7;105508:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:59;105500:86;;;::::0;-1:-1:-1;;;105500:86:0;;9080:2:1;105500:86:0::1;::::0;::::1;9062:21:1::0;9119:2;9099:18;;;9092:30;-1:-1:-1;;;9138:18:1;;;9131:44;9192:18;;105500:86:0::1;8878:338:1::0;103397:140:0;1940:7;1966:6;-1:-1:-1;;;;;1966:6:0;797:10;2106:23;2098:68;;;;-1:-1:-1;;;2098:68:0;;;;;;;:::i;:::-;103483:2:::1;103475:4;:10;;103467:35;;;::::0;-1:-1:-1;;;103467:35:0;;9423:2:1;103467:35:0::1;::::0;::::1;9405:21:1::0;9462:2;9442:18;;;9435:30;-1:-1:-1;;;9481:18:1;;;9474:42;9533:18;;103467:35:0::1;9221:336:1::0;103467:35:0::1;103512:11;:18:::0;103397:140::o;106708:477::-;106802:10;:17;106776:6;;106823:1;-1:-1:-1;106802:22:0;106794:62;;;;-1:-1:-1;;;106794:62:0;;9764:2:1;106794:62:0;;;9746:21:1;9803:2;9783:18;;;9776:30;9842:29;9822:18;;;9815:57;9889:18;;106794:62:0;9562:351:1;106794:62:0;106867:20;106897:23;106936:9;106968:1;106948:10;:17;;;;:21;;;;:::i;:::-;106936:33;;106931:198;106975:1;106971;:5;:46;;;;;107007:10;106980;106991:1;106980:13;;;;;;;;:::i;:::-;;;;;;;;;;;:23;;;:37;;106971:46;106931:198;;;107055:31;107077:5;107081:1;107077;:5;:::i;:::-;107084:1;107055:21;:31::i;:::-;107038:48;;;;:::i;:::-;;-1:-1:-1;107100:18:0;;;;:::i;:::-;;;;107019:3;;;;;:::i;:::-;;;;106931:198;;;-1:-1:-1;107146:32:0;107162:16;107146:13;:32;:::i;:::-;107139:39;106708:477;-1:-1:-1;;;;106708:477:0:o;2526:101::-;1940:7;1966:6;-1:-1:-1;;;;;1966:6:0;797:10;2106:23;2098:68;;;;-1:-1:-1;;;2098:68:0;;;;;;;:::i;:::-;2590:30:::1;2617:1;2590:18;:30::i;98220:113::-:0;98262:7;98288:38;98310:15;:13;:15::i;:::-;98288:17;:15;:17::i;:::-;:21;;:38::i;:::-;98281:45;;98220:113;:::o;104092:601::-;1940:7;1966:6;-1:-1:-1;;;;;1966:6:0;797:10;2106:23;2098:68;;;;-1:-1:-1;;;2098:68:0;;;;;;;:::i;:::-;104209:19;;;::::1;::::0;:55:::1;;-1:-1:-1::0;104232:32:0;;::::1;104209:55;104201:78;;;::::0;-1:-1:-1;;;104201:78:0;;11407:2:1;104201:78:0::1;::::0;::::1;11389:21:1::0;11446:2;11426:18;;;11419:30;-1:-1:-1;;;11465:18:1;;;11458:40;11515:18;;104201:78:0::1;11205:334:1::0;104201:78:0::1;104293:9;104289:349;104308:18:::0;;::::1;104289:349;;;104347:17;104387:18;104404:1;104387:7:::0;:18:::1;:::i;:::-;104382:1;:23;104378:150;;;-1:-1:-1::0;86890:42:0::1;104378:150;;;104499:7:::0;;104507:5:::1;:1:::0;104511::::1;104507:5;:::i;:::-;104499:14;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;104487:26;;104378:150;104542:85;104548:7;;104556:1;104548:10;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;104560:9;104571:7;;104579:1;104571:10;;;;;;;:::i;:::-;;;;;;;104590:7;;104598:1;104590:10;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;104583:43;::::0;-1:-1:-1;;;104583:43:0;;104620:4:::1;104583:43;::::0;::::1;856:51:1::0;-1:-1:-1;;;;;104583:28:0;;;::::1;::::0;::::1;::::0;829:18:1;;104583:43:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;104542:5;:85::i;:::-;-1:-1:-1::0;104328:3:0;::::1;::::0;::::1;:::i;:::-;;;;104289:349;;;;104647:14;104656:4;104647:8;:14::i;101913:135::-:0;101986:4;1966:6;;-1:-1:-1;;;;;1966:6:0;797:10;2106:23;2098:68;;;;-1:-1:-1;;;2098:68:0;;;;;;;:::i;:::-;-1:-1:-1;102000:8:0::1;:22:::0;;-1:-1:-1;;;;;;102000:22:0::1;-1:-1:-1::0;;;;;102000:22:0;::::1;;::::0;;-1:-1:-1;2176:1:0::1;101913:135:::0;;;:::o;99616:84::-;1940:7;1966:6;-1:-1:-1;;;;;1966:6:0;797:10;2106:23;2098:68;;;;-1:-1:-1;;;2098:68:0;;;;;;;:::i;:::-;99658:8:::1;:6;:8::i;:::-;99674:19;:17;:19::i;104772:530::-:0;1940:7;1966:6;-1:-1:-1;;;;;1966:6:0;797:10;2106:23;2098:68;;;;-1:-1:-1;;;2098:68:0;;;;;;;:::i;:::-;104881:12:::1;104903:5;;104909:1;104903:8;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;104941:30;::::0;-1:-1:-1;;;104941:30:0;;104965:4:::1;104941:30;::::0;::::1;856:51:1::0;104881:31:0;;-1:-1:-1;104922:16:0::1;::::0;-1:-1:-1;;;;;104941:15:0;::::1;::::0;::::1;::::0;829:18:1;;104941:30:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;104922:49:::0;-1:-1:-1;104981:46:0::1;-1:-1:-1::0;;;;;104981:27:0;::::1;105009:7:::0;104922:49;104981:27:::1;:46::i;:::-;-1:-1:-1::0;;;;;105038:80:0;::::1;;105132:8:::0;105154:1:::1;105169:5:::0;;105196:4:::1;105215:21;:15;105233:3;105215:21;:::i;:::-;105038:208;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;105256:14;105265:4;105256:8;:14::i;:::-;104871:431;;104772:530:::0;;;:::o;107895:1124::-;107987:6;108005:21;108029:10;108040:11;108029:23;;;;;;;;:::i;:::-;;;;;;;;;;;108005:47;;108062:19;108084:10;108095:9;108084:21;;;;;;;;:::i;:::-;;;;;;;;;;;108062:43;;108115:15;108133:4;108115:22;;108173:5;:21;;;108151:3;:19;;;:43;108147:92;;;-1:-1:-1;108223:5:0;108147:92;108249:32;108295:10;108291:212;;;108370:5;:21;;;108348:3;:19;;;:43;;;;:::i;:::-;108321:70;;108291:212;;;108473:3;:19;;;108449:5;:21;;;:43;;;;:::i;:::-;108422:70;;108291:212;108584:21;;;;108513:32;;108549:31;:24;108576:4;108549:31;:::i;:::-;108548:57;;;;:::i;:::-;108656:15;;108640:13;;108513:92;;-1:-1:-1;108615:22:0;;108640:31;;108656:15;108640:31;:::i;:::-;108615:56;-1:-1:-1;108682:38:0;108615:56;108724:35;88167:8;108724:24;:35;:::i;:::-;108723:54;;;;:::i;:::-;108682:95;-1:-1:-1;108787:38:0;108821:4;108682:95;108787:38;:::i;:::-;;;108874:10;108870:86;;;108914:30;-1:-1:-1;108900:45:0;;-1:-1:-1;;;;;;108900:45:0;108870:86;108973:39;108981:30;108973:39;:::i;:::-;108966:46;;;;;;;;;107895:1124;;;;;:::o;98420:121::-;98501:7;;98494:40;;-1:-1:-1;;;98494:40:0;;98528:4;98494:40;;;856:51:1;98468:7:0;;-1:-1:-1;;;;;98501:7:0;;98494:25;;829:18:1;;98494:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;101817:90::-;1940:7;1966:6;-1:-1:-1;;;;;1966:6:0;797:10;2106:23;2098:68;;;;-1:-1:-1;;;2098:68:0;;;;;;;:::i;:::-;101884:8:::1;:16:::0;101817:90::o;92197:120::-;92244:14;;;;;;;92243:15;92235:55;;;;-1:-1:-1;;;92235:55:0;;13421:2:1;92235:55:0;;;13403:21:1;13460:2;13440:18;;;13433:30;13499:29;13479:18;;;13472:57;13546:18;;92235:55:0;13219:351:1;100725:219:0;100793:4;1966:6;;-1:-1:-1;;;;;1966:6:0;797:10;2106:23;2098:68;;;;-1:-1:-1;;;2098:68:0;;;;;;;:::i;:::-;89718:3:::1;100815:9;:20;;100807:45;;;::::0;-1:-1:-1;;;100807:45:0;;7337:2:1;100807:45:0::1;::::0;::::1;7319:21:1::0;7376:2;7356:18;;;7349:30;-1:-1:-1;;;7395:18:1;;;7388:42;7447:18;;100807:45:0::1;7135:336:1::0;100807:45:0::1;100860:8;:20:::0;;;100893:25:::1;::::0;1064::1;;;100893::0::1;::::0;1052:2:1;1037:18;100893:25:0::1;;;;;;;;-1:-1:-1::0;100933:4:0::1;100725:219:::0;;;:::o;105797:139::-;1940:7;1966:6;-1:-1:-1;;;;;1966:6:0;797:10;2106:23;2098:68;;;;-1:-1:-1;;;2098:68:0;;;;;;;:::i;:::-;105889:17:::1;:40:::0;105797:139::o;103109:282::-;1940:7;1966:6;-1:-1:-1;;;;;1966:6:0;797:10;2106:23;2098:68;;;;-1:-1:-1;;;2098:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;103222:20:0;::::1;86890:42;103222:20;;103214:69;;;::::0;-1:-1:-1;;;103214:69:0;;13777:2:1;103214:69:0::1;::::0;::::1;13759:21:1::0;13816:2;13796:18;;;13789:30;13855:34;13835:18;;;13828:62;-1:-1:-1;;;13906:18:1;;;13899:34;13950:19;;103214:69:0::1;13575:400:1::0;103214:69:0::1;103293:12;:21:::0;;-1:-1:-1;;;;;103324:25:0;;::::1;103293:21;103324:25;-1:-1:-1::0;;;;;;103293:21:0;::::1;;103324:25:::0;;;;-1:-1:-1;;;;;;103324:25:0;;;;;;;;;;::::1;::::0;;103359:17:::1;:25:::0;103109:282::o;106147:307::-;106213:22;106269:2;106255:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;106255:17:0;;;;;;;;;;;;;;;;106247:25;;106282:20;106322:9;106354:2;106334:10;:17;;;;:22;;;;:::i;:::-;106322:34;;106317:131;106362:10;:17;106358:21;;106317:131;;;106424:10;106435:1;106424:13;;;;;;;;:::i;:::-;;;;;;;;;;;106400:37;;;;;;;;;;;;;;;;;;;;;;;;;:5;106406:14;;;;;:::i;:::-;;;106400:21;;;;;;;;:::i;:::-;;;;;;:37;;;;106381:3;;;;;:::i;:::-;;;;106317:131;;;;106237:217;106147:307;;;:::o;2776:198::-;1940:7;1966:6;-1:-1:-1;;;;;1966:6:0;797:10;2106:23;2098:68;;;;-1:-1:-1;;;2098:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;2864:22:0;::::1;2856:73;;;::::0;-1:-1:-1;;;2856:73:0;;14314:2:1;2856:73:0::1;::::0;::::1;14296:21:1::0;14353:2;14333:18;;;14326:30;14392:34;14372:18;;;14365:62;-1:-1:-1;;;14443:18:1;;;14436:36;14489:19;;2856:73:0::1;14112:402:1::0;2856:73:0::1;2939:28;2958:8;2939:18;:28::i;:::-;2776:198:::0;:::o;88051:27::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;88051:27:0;:::o;107423:466::-;107522:10;:17;107496:6;;107543:1;-1:-1:-1;107522:22:0;107514:62;;;;-1:-1:-1;;;107514:62:0;;9764:2:1;107514:62:0;;;9746:21:1;9803:2;9783:18;;;9776:30;9842:29;9822:18;;;9815:57;9889:18;;107514:62:0;9562:351:1;107514:62:0;107587:20;107617:23;107656:9;107688:1;107668:10;:17;;;;:21;;;;:::i;:::-;107656:33;;107651:182;107695:1;107691;:5;:30;;;;;107719:2;107700:16;:21;107691:30;107651:182;;;107759:31;107781:5;107785:1;107781;:5;:::i;107759:31::-;107742:48;;;;:::i;:::-;;-1:-1:-1;107804:18:0;;;;:::i;:::-;;;;107723:3;;;;;:::i;:::-;;;;107651:182;;101330:223;101396:4;1966:6;;-1:-1:-1;;;;;1966:6:0;797:10;2106:23;2098:68;;;;-1:-1:-1;;;2098:68:0;;;;;;;:::i;:::-;101410:7:::1;:18:::0;;;101450:28:::1;89822:5;101420:8:::0;101450:19:::1;:28::i;:::-;101436:11;:42:::0;;;101506:7:::1;::::0;101491:36:::1;::::0;::::1;::::0;::::1;::::0;6232:25:1;;6288:2;6273:18;;6266:34;6220:2;6205:18;;6058:248;101559:131:0;101627:4;1966:6;;-1:-1:-1;;;;;1966:6:0;797:10;2106:23;2098:68;;;;-1:-1:-1;;;2098:68:0;;;;;;;:::i;:::-;-1:-1:-1;101642:9:0::1;:20:::0;;-1:-1:-1;;101642:20:0::1;::::0;::::1;;::::0;;;::::1;::::0;;-1:-1:-1;;101559:131:0:o;99016:301::-;99080:5;;-1:-1:-1;;;;;99080:5:0;99066:10;:19;99058:38;;;;-1:-1:-1;;;99058:38:0;;8207:2:1;99058:38:0;;;8189:21:1;8246:1;8226:18;;;8219:29;-1:-1:-1;;;8264:18:1;;;8257:36;8310:18;;99058:38:0;8005:329:1;99058:38:0;99121:10;;;;;;;;;-1:-1:-1;;;;;99121:10:0;-1:-1:-1;;;;;99107:44:0;;99152:6;;99160:15;:13;:15::i;:::-;99107:84;;-1:-1:-1;;;;;;99107:84:0;;;;;;;;;;8730:25:1;;;;8771:18;;;8764:34;99185:4:0;8814:18:1;;;8807:60;8703:18;;99107:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;99227:7:0;;99220:40;;-1:-1:-1;;;99220:40:0;;99254:4;99220:40;;;856:51:1;99202:15:0;;-1:-1:-1;;;;;;99227:7:0;;;;-1:-1:-1;99220:25:0;;829:18:1;;99220:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;99277:7;;99295:5;;99270:40;;-1:-1:-1;;;99270:40:0;;-1:-1:-1;;;;;99295:5:0;;;99270:40;;;14693:51:1;14760:18;;;14753:34;;;99202:58:0;;-1:-1:-1;99277:7:0;;99270:24;;14666:18:1;;99270:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;99048:269;99016:301::o;34188:603::-;34543:10;;;34542:62;;-1:-1:-1;34559:39:0;;-1:-1:-1;;;34559:39:0;;34583:4;34559:39;;;15260:34:1;-1:-1:-1;;;;;15330:15:1;;;15310:18;;;15303:43;34559:15:0;;;;;15195:18:1;;34559:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;34542:62;34521:163;;;;-1:-1:-1;;;34521:163:0;;15559:2:1;34521:163:0;;;15541:21:1;15598:2;15578:18;;;15571:30;15637:34;15617:18;;;15610:62;-1:-1:-1;;;15688:18:1;;;15681:52;15750:19;;34521:163:0;15357:418:1;34521:163:0;34721:62;;-1:-1:-1;;;;;14711:32:1;;34721:62:0;;;14693:51:1;14760:18;;;14753:34;;;34694:90:0;;34714:5;;-1:-1:-1;;;34744:22:0;14666:18:1;;34721:62:0;;;;-1:-1:-1;;34721:62:0;;;;;;;;;;;;;;-1:-1:-1;;;;;34721:62:0;-1:-1:-1;;;;;;34721:62:0;;;;;;;;;;34694:19;:90::i;16274:223::-;16407:12;16438:52;16460:6;16468:4;16474:1;16477:12;16438:21;:52::i;:::-;16431:59;;16274:223;;;;;;:::o;93805:656::-;37772:4;37795:7;-1:-1:-1;;;37795:7:0;;;;38038:9;38030:38;;;;-1:-1:-1;;;38030:38:0;;;;;;;:::i;:::-;93893:10:::1;::::0;93913:6:::1;::::0;;93879:56:::1;::::0;-1:-1:-1;;;93879:56:0;;;;::::1;7030:25:1::0;93929:4:0::1;7071:18:1::0;;;7064:60;93893:10:0;;;::::1;-1:-1:-1::0;;;;;93893:10:0::1;::::0;93879:33:::1;::::0;7003:18:1;;93879:56:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;93945:29;93957:16;93945:11;:29::i;:::-;93988:12;::::0;::::1;;93985:73;;;94019:17;::::0;94038::::1;::::0;94002:54:::1;::::0;94019:17:::1;::::0;::::1;-1:-1:-1::0;;;;;94019:17:0::1;::::0;94002:16:::1;:54::i;:::-;94095:13;::::0;94068:41:::1;::::0;86890:42:::1;::::0;94095:13:::1;;94068;:41::i;:::-;94120:9;:7;:9::i;:::-;94140:10;:8;:10::i;:::-;94230:17;::::0;94184:10:::1;94195:17:::0;;:21:::1;::::0;94215:1:::1;::::0;94195:21:::1;:::i;:::-;94184:33;;;;;;;;:::i;:::-;;;;;;;;;;;:43;;;:63;;;;:::i;:::-;94165:15;:82;94161:254;;94296:94;::::0;;;;::::1;::::0;;94316:15:::1;94296:94:::0;;94359:5:::1;::::0;94350:38;;-1:-1:-1;;;94350:38:0;;;;94263:10:::1;::::0;94296:94:::1;::::0;;::::1;::::0;-1:-1:-1;;;;;94359:5:0::1;::::0;94350:36:::1;::::0;:38:::1;::::0;;::::1;::::0;94296:94;94350:38;;;;;;94359:5;94350:38;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;94296:94:::0;;94263:141;;::::1;::::0;;::::1;::::0;;-1:-1:-1;94263:141:0;;;::::1;::::0;;;;;;::::1;::::0;;::::1;;::::0;;;;;;::::1;::::0;;::::1;::::0;94161:254:::1;94430:24;::::0;94443:10:::1;::::0;94430:24:::1;::::0;;;::::1;93805:656:::0;:::o;9131:96::-;9189:7;9215:5;9219:1;9215;:5;:::i;9474:96::-;9532:7;9558:5;9562:1;9558;:5;:::i;9859:96::-;9917:7;9943:5;9947:1;9943;:5;:::i;33476:205::-;33615:58;;-1:-1:-1;;;;;14711:32:1;;33615:58:0;;;14693:51:1;14760:18;;;14753:34;;;33588:86:0;;33608:5;;-1:-1:-1;;;33638:23:0;14666:18:1;;33615:58:0;14519:274:1;38737:117:0;37772:4;37795:7;-1:-1:-1;;;37795:7:0;;;;38296:41;;;;-1:-1:-1;;;38296:41:0;;16327:2:1;38296:41:0;;;16309:21:1;16366:2;16346:18;;;16339:30;-1:-1:-1;;;16385:18:1;;;16378:50;16445:18;;38296:41:0;16125:344:1;38296:41:0;38805:5:::1;38795:15:::0;;-1:-1:-1;;;;38795:15:0::1;::::0;;38825:22:::1;797:10:::0;38834:12:::1;38825:22;::::0;-1:-1:-1;;;;;874:32:1;;;856:51;;844:2;829:18;38825:22:0::1;;;;;;;38737:117::o:0;99874:522::-;99920:43;86705:42;86795;99961:1;99920:32;:43::i;:::-;99973:45;86890:42;-1:-1:-1;;;;;;;;;;;100016:1:0;99973:31;:45::i;:::-;100028:38;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;100064:1:0;100028:24;:38::i;:::-;100103:10;;100076:41;;86795:42;;100103:10;;;-1:-1:-1;;;;;100103:10:0;100115:1;100076:26;:41::i;:::-;100127:59;86705:42;86795;-1:-1:-1;;100127:32:0;:59::i;:::-;100196:61;86890:42;-1:-1:-1;;;;;;;;;;;;;100196:31:0;:61::i;:::-;100267:54;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;100267:24:0;:54::i;:::-;100358:10;;100331:57;;86795:42;;100358:10;;;-1:-1:-1;;;;;100358:10:0;-1:-1:-1;;100331:26:0;:57::i;92323:250::-;37772:4;37795:7;-1:-1:-1;;;37795:7:0;;;;38038:9;38030:38;;;;-1:-1:-1;;;38030:38:0;;;;;;;:::i;:::-;101736:9:::1;::::0;::::1;;:17;;:9:::0;:17:::1;101732:62;;;101768:15;101777:5;101768:8;:15::i;:::-;92416:7:::2;::::0;92409:40:::2;::::0;-1:-1:-1;;;92409:40:0;;92443:4:::2;92409:40;::::0;::::2;856:51:1::0;92391:15:0::2;::::0;-1:-1:-1;;;;;92416:7:0::2;::::0;92409:25:::2;::::0;829:18:1;;92409:40:0::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;92391:58:::0;-1:-1:-1;92464:11:0;;92460:107:::2;;92505:10;::::0;92525:6:::2;::::0;;92491:65:::2;::::0;-1:-1:-1;;;92491:65:0;;;;::::2;8730:25:1::0;8771:18;;;8764:34;;;92550:4:0::2;8814:18:1::0;;;8807:60;92505:10:0;;;::::2;-1:-1:-1::0;;;;;92505:10:0::2;::::0;92491:33:::2;::::0;8703:18:1;;92491:65:0::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;3128:187:::0;3201:16;3220:6;;-1:-1:-1;;;;;3236:17:0;;;-1:-1:-1;;;;;;3236:17:0;;;;;;3268:40;;3220:6;;;;;;;3268:40;;3201:16;3268:40;3191:124;3128:187;:::o;8764:96::-;8822:7;8848:5;8852:1;8848;:5;:::i;95904:862::-;96006:35;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96006:35:0;96113:25;;;96051:24;96148:15;;;;:26;;;-1:-1:-1;;;;;96184:37:0;;;:18;;;;:37;;;96231:39;;;:19;;;;:39;;;;96280:17;;;;:26;;;96338:13;;;;;1793:36:1;;;96338:13:0;;;;;;;;;1766:18:1;;;96338:13:0;;96316:19;;;:35;-1:-1:-1;;;;;;;;;;;;;;;;;;96429:4:0;96406:28;;;-1:-1:-1;;;96487:40:0;;;;96579:42;;-1:-1:-1;;;;;;;;;;;96051:24:0;96579:28;:42::i;:::-;96631:47;-1:-1:-1;;;;;96631:28:0;;-1:-1:-1;;;;;;;;;;;96671:6:0;96631:28;:47::i;:::-;-1:-1:-1;;;;;;;;;;;96689:22:0;96712:10;96724:5;96731:1;96735:21;:15;96753:3;96735:21;:::i;:::-;96689:69;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;95995:771;;;95904:862;;;;:::o;38490:115::-;37772:4;37795:7;-1:-1:-1;;;37795:7:0;;;;38038:9;38030:38;;;;-1:-1:-1;;;38030:38:0;;;;;;;:::i;:::-;38549:7:::1;:14:::0;;-1:-1:-1;;;;38549:14:0::1;-1:-1:-1::0;;;38549:14:0::1;::::0;;38578:20:::1;38585:12;797:10:::0;;718:96;100402:252;100450:43;86705:42;86795;100491:1;100450:32;:43::i;:::-;100503:45;86890:42;-1:-1:-1;;;;;;;;;;;100546:1:0;100503:31;:45::i;:::-;100558:38;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;100594:1:0;100558:24;:38::i;:::-;100633:10;;100606:41;;86795:42;;100633:10;;;-1:-1:-1;;;;;100633:10:0;100645:1;100606:26;:41::i;34797:310::-;34946:39;;-1:-1:-1;;;34946:39:0;;34970:4;34946:39;;;15260:34:1;-1:-1:-1;;;;;15330:15:1;;;15310:18;;;15303:43;34923:20:0;;34988:5;;34946:15;;;;;15195:18:1;;34946:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:47;;;;:::i;:::-;35030:69;;-1:-1:-1;;;;;14711:32:1;;35030:69:0;;;14693:51:1;14760:18;;;14753:34;;;34923:70:0;;-1:-1:-1;35003:97:0;;35023:5;;-1:-1:-1;;;35053:22:0;14666:18:1;;35030:69:0;14519:274:1;35982:706:0;36401:23;36427:69;36455:4;36427:69;;;;;;;;;;;;;;;;;36435:5;-1:-1:-1;;;;;36427:27:0;;;:69;;;;;:::i;:::-;36510:17;;36401:95;;-1:-1:-1;36510:21:0;36506:176;;36605:10;36594:30;;;;;;;;;;;;:::i;:::-;36586:85;;;;-1:-1:-1;;;36586:85:0;;19079:2:1;36586:85:0;;;19061:21:1;19118:2;19098:18;;;19091:30;19157:34;19137:18;;;19130:62;-1:-1:-1;;;19208:18:1;;;19201:40;19258:19;;36586:85:0;18877:406:1;17361:499:0;17526:12;17583:5;17558:21;:30;;17550:81;;;;-1:-1:-1;;;17550:81:0;;19490:2:1;17550:81:0;;;19472:21:1;19529:2;19509:18;;;19502:30;19568:34;19548:18;;;19541:62;-1:-1:-1;;;19619:18:1;;;19612:36;19665:19;;17550:81:0;19288:402:1;17550:81:0;13847:20;;17641:60;;;;-1:-1:-1;;;17641:60:0;;19897:2:1;17641:60:0;;;19879:21:1;19936:2;19916:18;;;19909:30;19975:31;19955:18;;;19948:59;20024:18;;17641:60:0;19695:353:1;17641:60:0;17713:12;17727:23;17754:6;-1:-1:-1;;;;;17754:11:0;17773:5;17780:4;17754:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17712:73;;;;17802:51;17819:7;17828:10;17840:12;17802:16;:51::i;:::-;17795:58;17361:499;-1:-1:-1;;;;;;;17361:499:0:o;94787:1027::-;94870:44;;-1:-1:-1;;;94870:44:0;;94908:4;94870:44;;;856:51:1;94850:17:0;;86890:42;;94870:29;;829:18:1;;94870:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;94942:37;;-1:-1:-1;;;94942:37:0;;94973:4;94942:37;;;856:51:1;94850:64:0;;-1:-1:-1;94924:15:0;;-1:-1:-1;;;;;;;;;;;86609:42:0;94942:22;;829:18:1;;94942:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;94924:55;;94990:12;95012:16;95056:44;89822:5;95056:23;95070:8;;95056:9;:13;;:23;;;;:::i;:44::-;95049:51;-1:-1:-1;95110:44:0;86890:42;-1:-1:-1;;;;;;;;;;;87775:66:0;95049:51;95110:5;:44::i;:::-;95175:37;;-1:-1:-1;;;95175:37:0;;95206:4;95175:37;;;856:51:1;95175:50:0;;95217:7;;-1:-1:-1;;;;;;;;;;;86609:42:0;95175:22;;829:18:1;;95175:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;:50::i;:::-;95164:61;;95236:21;95260:42;89822:5;95260:21;95273:7;;95260:8;:12;;:21;;;;:::i;:42::-;95236:66;-1:-1:-1;95312:52:0;-1:-1:-1;;;;;;;;;;;95338:10:0;95236:66;95312:25;:52::i;:::-;95376:26;95405:46;89822:5;95405:25;95418:11;;95405:8;:12;;:25;;;;:::i;:46::-;95376:75;;95465:16;95461:281;;;95497:23;95523:58;89822:5;95523:37;95546:13;;95523:18;:22;;:37;;;;:::i;:58::-;95497:84;-1:-1:-1;95616:39:0;:18;95497:84;95616:22;:39::i;:::-;95695:18;;95595:60;;-1:-1:-1;95669:62:0;;-1:-1:-1;;;;;;;;;;;86609:42:0;-1:-1:-1;;;;;95695:18:0;95715:15;95669:25;:62::i;:::-;95483:259;95461:281;95777:8;;95751:55;;-1:-1:-1;;;;;;;;;;;86609:42:0;-1:-1:-1;;;;;95777:8:0;95787:18;95751:25;:55::i;102054:815::-;102152:37;;-1:-1:-1;;;102152:37:0;;102183:4;102152:37;;;856:51:1;102134:15:0;;-1:-1:-1;;;;;;;;;;;86609:42:0;102152:22;;829:18:1;;102152:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;102217:38;;-1:-1:-1;;;102217:38:0;;102249:4;102217:38;;;856:51:1;102134:55:0;;-1:-1:-1;102203:11:0;;-1:-1:-1;;;;;102217:23:0;;;;;829:18:1;;102217:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;102203:52;;102269:30;102275:5;-1:-1:-1;;;;;;;;;;;102288:5:0;102295:3;102269:5;:30::i;:::-;102383:8;;102328:37;;-1:-1:-1;;;102328:37:0;;102359:4;102328:37;;;856:51:1;102313:12:0;;102328:85;;89822:5;;102328:64;;:50;;102370:7;;-1:-1:-1;;;;;;;;;;;86609:42:0;102328:22;;829:18:1;;102328:37:0;710:203:1;102328:50:0;:54;;:64::i;:85::-;102313:100;;102428:21;102452:38;89822:5;102452:17;102461:7;;102452:4;:8;;:17;;;;:::i;:38::-;102428:62;-1:-1:-1;102504:52:0;-1:-1:-1;;;;;;;;;;;102530:10:0;102428:62;102504:25;:52::i;:::-;102571:26;102600:42;89822:5;102600:21;102609:11;;102600:4;:8;;:21;;;;:::i;:42::-;102682:8;;102571:71;;-1:-1:-1;102656:55:0;;-1:-1:-1;;;;;;;;;;;86609:42:0;-1:-1:-1;;;;;102682:8:0;102571:71;102656:25;:55::i;:::-;102749:37;;-1:-1:-1;;;102749:37:0;;102780:4;102749:37;;;856:51:1;-1:-1:-1;;;;;;;;;;;86609:42:0;102749:22;;829:18:1;;102749:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;102739:47;-1:-1:-1;102800:47:0;-1:-1:-1;;;;;;;;;;;86890:42:0;87775:66;102739:47;102800:5;:47::i;96874:1144::-;96977:38;;-1:-1:-1;;;96977:38:0;;97009:4;96977:38;;;856:51:1;96947:27:0;;-1:-1:-1;;;;;96977:23:0;;;;;829:18:1;;96977:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;96947:68;-1:-1:-1;97026:39:0;-1:-1:-1;;;;;97026:25:0;;-1:-1:-1;;;;;;;;;;;97063:1:0;97026:25;:39::i;:::-;97075:57;-1:-1:-1;;;;;97075:25:0;;-1:-1:-1;;;;;;;;;;;97112:19:0;97075:25;:57::i;:::-;97181:54;97288:21;;97143:35;;-1:-1:-1;;;97288:21:0;;;;97274:36;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;97274:36:0;;97245:65;;97342:19;97320:9;97330:8;97320:19;;;;;;;;;;:::i;:::-;;;;;;;;;;:41;97394:1;97444:21;;97371:20;;-1:-1:-1;;;97444:21:0;;;;97431:35;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;97431:35:0;;97405:61;;97480:7;97476:100;97497:21;;;-1:-1:-1;;;97497:21:0;;;;;97493:25;;;;97476:100;;;97558:6;;;;;;;:3;:6;;;;;;97538:10;;-1:-1:-1;;;;;97558:6:0;;;;97538:7;;:10;;;;;;:::i;:::-;-1:-1:-1;;;;;97538:27:0;;;:10;;;;;;;;;;;:27;97520:3;;;;:::i;:::-;;;;97476:100;;;;97588:21;97623:8;97633:9;97644:12;97612:45;;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;97612:45:0;;;-1:-1:-1;;;;;;;;;;97715:24:0;;;97612:45;-1:-1:-1;;97749:32:0;;;-1:-1:-1;;;97791:27:0;;;97914:12;;97874:137;;-1:-1:-1;;;97874:137:0;;97612:45;;-1:-1:-1;;;;;;;;;;;;86997:42:0;97874:26;;:137;;97914:12;97948:4;;;;97612:45;;97874:137;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96937:1081;;;;;;;96874:1144;;:::o;94467:146::-;94521:45;;-1:-1:-1;;;94521:45:0;;94560:4;94521:45;;;856:51:1;94505:13:0;;86705:42;;94521:30;;829:18:1;;94521:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;94576:30;;-1:-1:-1;;;94576:30:0;;;;;1064:25:1;;;94505:61:0;;-1:-1:-1;86795:42:0;;94576:23;;1037:18:1;;94576:30:0;918:177:1;19974:692:0;20120:12;20148:7;20144:516;;;-1:-1:-1;20178:10:0;20171:17;;20144:516;20289:17;;:21;20285:365;;20483:10;20477:17;20543:15;20530:10;20526:2;20522:19;20515:44;20285:365;20622:12;20615:20;;-1:-1:-1;;;20615:20:0;;;;;;;;:::i;14:173:1:-;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:70;;177:1;174;167:12;192:328;269:6;277;285;338:2;326:9;317:7;313:23;309:32;306:52;;;354:1;351;344:12;306:52;377:29;396:9;377:29;:::i;:::-;367:39;;453:2;442:9;438:18;425:32;415:42;;476:38;510:2;499:9;495:18;476:38;:::i;:::-;466:48;;192:328;;;;;:::o;525:180::-;584:6;637:2;625:9;616:7;612:23;608:32;605:52;;;653:1;650;643:12;605:52;-1:-1:-1;676:23:1;;525:180;-1:-1:-1;525:180:1:o;1100:118::-;1186:5;1179:13;1172:21;1165:5;1162:32;1152:60;;1208:1;1205;1198:12;1223:241;1279:6;1332:2;1320:9;1311:7;1307:23;1303:32;1300:52;;;1348:1;1345;1338:12;1300:52;1387:9;1374:23;1406:28;1428:5;1406:28;:::i;1840:186::-;1899:6;1952:2;1940:9;1931:7;1927:23;1923:32;1920:52;;;1968:1;1965;1958:12;1920:52;1991:29;2010:9;1991:29;:::i;2499:367::-;2562:8;2572:6;2626:3;2619:4;2611:6;2607:17;2603:27;2593:55;;2644:1;2641;2634:12;2593:55;-1:-1:-1;2667:20:1;;2710:18;2699:30;;2696:50;;;2742:1;2739;2732:12;2696:50;2779:4;2771:6;2767:17;2755:29;;2839:3;2832:4;2822:6;2819:1;2815:14;2807:6;2803:27;2799:38;2796:47;2793:67;;;2856:1;2853;2846:12;2793:67;2499:367;;;;;:::o;2871:773::-;2993:6;3001;3009;3017;3070:2;3058:9;3049:7;3045:23;3041:32;3038:52;;;3086:1;3083;3076:12;3038:52;3126:9;3113:23;3155:18;3196:2;3188:6;3185:14;3182:34;;;3212:1;3209;3202:12;3182:34;3251:70;3313:7;3304:6;3293:9;3289:22;3251:70;:::i;:::-;3340:8;;-1:-1:-1;3225:96:1;-1:-1:-1;3428:2:1;3413:18;;3400:32;;-1:-1:-1;3444:16:1;;;3441:36;;;3473:1;3470;3463:12;3441:36;;3512:72;3576:7;3565:8;3554:9;3550:24;3512:72;:::i;:::-;2871:773;;;;-1:-1:-1;3603:8:1;-1:-1:-1;;;;2871:773:1:o;3649:511::-;3744:6;3752;3760;3813:2;3801:9;3792:7;3788:23;3784:32;3781:52;;;3829:1;3826;3819:12;3781:52;3852:29;3871:9;3852:29;:::i;:::-;3842:39;;3932:2;3921:9;3917:18;3904:32;3959:18;3951:6;3948:30;3945:50;;;3991:1;3988;3981:12;3945:50;4030:70;4092:7;4083:6;4072:9;4068:22;4030:70;:::i;:::-;3649:511;;4119:8;;-1:-1:-1;4004:96:1;;-1:-1:-1;;;;3649:511:1:o;4165:269::-;4222:6;4275:2;4263:9;4254:7;4250:23;4246:32;4243:52;;;4291:1;4288;4281:12;4243:52;4330:9;4317:23;4380:4;4373:5;4369:16;4362:5;4359:27;4349:55;;4400:1;4397;4390:12;4439:248;4507:6;4515;4568:2;4556:9;4547:7;4543:23;4539:32;4536:52;;;4584:1;4581;4574:12;4536:52;-1:-1:-1;;4607:23:1;;;4677:2;4662:18;;;4649:32;;-1:-1:-1;4439:248:1:o;4877:383::-;4951:6;4959;4967;5020:2;5008:9;4999:7;4995:23;4991:32;4988:52;;;5036:1;5033;5026:12;4988:52;5075:9;5062:23;5094:28;5116:5;5094:28;:::i;:::-;5141:5;-1:-1:-1;5165:38:1;5199:2;5184:18;;5165:38;:::i;:::-;5155:48;;5250:2;5239:9;5235:18;5222:32;5212:42;;4877:383;;;;;:::o;5265:788::-;5486:2;5538:21;;;5608:13;;5511:18;;;5630:22;;;5457:4;;5486:2;5671;;5689:18;;;;5730:15;;;5457:4;5773:254;5787:6;5784:1;5781:13;5773:254;;;5846:13;;5884:9;;5872:22;;5934:11;;5928:18;5914:12;;;5907:40;5967:12;;;;6002:15;;;;5809:1;5802:9;5773:254;;;-1:-1:-1;6044:3:1;;5265:788;-1:-1:-1;;;;;;;5265:788:1:o;6495:356::-;6697:2;6679:21;;;6716:18;;;6709:30;6775:34;6770:2;6755:18;;6748:62;6842:2;6827:18;;6495:356::o;7755:245::-;7834:6;7842;7895:2;7883:9;7874:7;7870:23;7866:32;7863:52;;;7911:1;7908;7901:12;7863:52;-1:-1:-1;;7934:16:1;;7990:2;7975:18;;;7969:25;7934:16;;7969:25;;-1:-1:-1;7755:245:1:o;8339:184::-;8409:6;8462:2;8450:9;8441:7;8437:23;8433:32;8430:52;;;8478:1;8475;8468:12;8430:52;-1:-1:-1;8501:16:1;;8339:184;-1:-1:-1;8339:184:1:o;9918:127::-;9979:10;9974:3;9970:20;9967:1;9960:31;10010:4;10007:1;10000:15;10034:4;10031:1;10024:15;10050:125;10090:4;10118:1;10115;10112:8;10109:34;;;10123:18;;:::i;:::-;-1:-1:-1;10160:9:1;;10050:125::o;10180:127::-;10241:10;10236:3;10232:20;10229:1;10222:31;10272:4;10269:1;10262:15;10296:4;10293:1;10286:15;10312:265;10351:3;10379:9;;;10404:10;;-1:-1:-1;;;;;10423:27:1;;;10416:35;;10400:52;10397:78;;;10455:18;;:::i;:::-;-1:-1:-1;;;10502:19:1;;;10495:27;;10487:36;;10484:62;;;10526:18;;:::i;:::-;-1:-1:-1;;10562:9:1;;10312:265::o;10582:147::-;10620:3;-1:-1:-1;;;;;10641:30:1;;10638:56;;;10674:18;;:::i;:::-;-1:-1:-1;10721:1:1;10710:13;;10582:147::o;10734:136::-;10773:3;10801:5;10791:39;;10810:18;;:::i;:::-;-1:-1:-1;;;10846:18:1;;10734:136::o;10875:127::-;10936:10;10931:3;10927:20;10924:1;10917:31;10967:4;10964:1;10957:15;10991:4;10988:1;10981:15;11007:193;11046:1;11072;11062:35;;11077:18;;:::i;:::-;-1:-1:-1;;;11113:18:1;;-1:-1:-1;;11133:13:1;;11109:38;11106:64;;;11150:18;;:::i;:::-;-1:-1:-1;11184:10:1;;11007:193::o;11544:128::-;11584:3;11615:1;11611:6;11608:1;11605:13;11602:39;;;11621:18;;:::i;:::-;-1:-1:-1;11657:9:1;;11544:128::o;11677:135::-;11716:3;-1:-1:-1;;11737:17:1;;11734:43;;;11757:18;;:::i;11817:958::-;12150:25;;;12194:2;12212:18;;;12205:34;;;12137:3;12270:2;12255:18;;12248:31;;;12122:19;;12314:22;;;12089:4;;12394:6;;12367:3;12352:19;;12089:4;12428:208;12442:6;12439:1;12436:13;12428:208;;;-1:-1:-1;;;;;12507:26:1;12526:6;12507:26;:::i;:::-;12503:52;12491:65;;12611:15;;;;12576:12;;;;12464:1;12457:9;12428:208;;;-1:-1:-1;;;;;;12692:32:1;;;;12687:2;12672:18;;12665:60;-1:-1:-1;;;12756:3:1;12741:19;12734:35;12653:3;11817:958;-1:-1:-1;;;;11817:958:1:o;12780:168::-;12820:7;12886:1;12882;12878:6;12874:14;12871:1;12868:21;12863:1;12856:9;12849:17;12845:45;12842:71;;;12893:18;;:::i;:::-;-1:-1:-1;12933:9:1;;12780:168::o;12953:120::-;12993:1;13019;13009:35;;13024:18;;:::i;:::-;-1:-1:-1;13058:9:1;;12953:120::o;13078:136::-;13113:3;-1:-1:-1;;;13134:22:1;;13131:48;;;13159:18;;:::i;:::-;-1:-1:-1;13199:1:1;13195:13;;13078:136::o;13980:127::-;14041:10;14036:3;14032:20;14029:1;14022:31;14072:4;14069:1;14062:15;14096:4;14093:1;14086:15;14798:245;14865:6;14918:2;14906:9;14897:7;14893:23;14889:32;14886:52;;;14934:1;14931;14924:12;14886:52;14966:9;14960:16;14985:28;15007:5;14985:28;:::i;15780:340::-;15982:2;15964:21;;;16021:2;16001:18;;;15994:30;-1:-1:-1;;;16055:2:1;16040:18;;16033:46;16111:2;16096:18;;15780:340::o;16474:127::-;16535:10;16530:3;16526:20;16523:1;16516:31;16566:4;16563:1;16556:15;16590:4;16587:1;16580:15;16805:258;16877:1;16887:113;16901:6;16898:1;16895:13;16887:113;;;16977:11;;;16971:18;16958:11;;;16951:39;16923:2;16916:10;16887:113;;;17018:6;17015:1;17012:13;17009:48;;;-1:-1:-1;;17053:1:1;17035:16;;17028:27;16805:258::o;17068:257::-;17109:3;17147:5;17141:12;17174:6;17169:3;17162:19;17190:63;17246:6;17239:4;17234:3;17230:14;17223:4;17216:5;17212:16;17190:63;:::i;:::-;17307:2;17286:15;-1:-1:-1;;17282:29:1;17273:39;;;;17314:4;17269:50;;17068:257;-1:-1:-1;;17068:257:1:o;17690:1182::-;18031:3;18020:9;18013:22;18078:6;18072:13;18066:3;18055:9;18051:19;18044:42;17994:4;18133;18125:6;18121:17;18115:24;18175:1;18161:12;18158:19;18148:53;;18181:18;;:::i;:::-;18232:3;18217:19;;18210:41;18300:4;18288:17;;18282:24;-1:-1:-1;;;;;18381:23:1;;;18375:3;18360:19;;18353:52;18464:4;18452:17;;18446:24;18442:33;18436:3;18421:19;;18414:62;18531:4;18519:17;;18513:24;18507:3;18492:19;;18485:53;18333:3;18575:17;;18569:24;18630:4;18624:3;18609:19;;18602:33;18652:53;18700:3;18685:19;;18569:24;18652:53;:::i;:::-;18644:61;;;18714:62;18770:4;18759:9;18755:20;18747:6;17452:12;;-1:-1:-1;;;;;17448:21:1;;;17436:34;;17533:4;17522:16;;;17516:23;17509:31;17502:39;17486:14;;;17479:63;17595:4;17584:16;;;17578:23;17574:32;;;17558:14;;;17551:56;17670:4;17659:16;;;17653:23;17646:31;17639:39;17623:14;;17616:63;17330:355;18714:62;18807:4;18792:20;;18785:36;;;;18852:4;18837:20;18830:36;17690:1182;;-1:-1:-1;;17690:1182:1:o;20053:274::-;20182:3;20220:6;20214:13;20236:53;20282:6;20277:3;20270:4;20262:6;20258:17;20236:53;:::i;:::-;20305:16;;;;;20053:274;-1:-1:-1;;20053:274:1:o;20332:175::-;20369:3;20413:4;20406:5;20402:16;20442:4;20433:7;20430:17;20427:43;;;20450:18;;:::i;:::-;20499:1;20486:15;;20332:175;-1:-1:-1;;20332:175:1:o;20512:435::-;20565:3;20603:5;20597:12;20630:6;20625:3;20618:19;20656:4;20685:2;20680:3;20676:12;20669:19;;20722:2;20715:5;20711:14;20743:1;20753:169;20767:6;20764:1;20761:13;20753:169;;;20828:13;;20816:26;;20862:12;;;;20897:15;;;;20789:1;20782:9;20753:169;;;-1:-1:-1;20938:3:1;;20512:435;-1:-1:-1;;;;;20512:435:1:o;20952:470::-;21161:4;21201:1;21193:6;21190:13;21180:47;;21207:18;;:::i;:::-;21254:6;21243:9;21236:25;21297:2;21292;21281:9;21277:18;21270:30;21317:56;21369:2;21358:9;21354:18;21346:6;21317:56;:::i;:::-;21309:64;;21409:6;21404:2;21393:9;21389:18;21382:34;20952:470;;;;;;:::o;21427:1544::-;21706:6;21695:9;21688:25;21669:4;21732:2;21770:1;21766;21761:3;21757:11;21753:19;21820:2;21812:6;21808:15;21803:2;21792:9;21788:18;21781:43;21872:2;21864:6;21860:15;21855:2;21844:9;21840:18;21833:43;21912:3;21907:2;21896:9;21892:18;21885:31;21954:3;21943:9;21939:19;21993:6;21987:13;22037:3;22031;22020:9;22016:19;22009:32;22061:6;22096:12;22090:19;22133:6;22125;22118:22;22171:3;22160:9;22156:19;22149:26;;22216:2;22202:12;22198:21;22184:35;;22237:1;22228:10;;22247:178;22261:6;22258:1;22255:13;22247:178;;;22326:13;;22322:22;;22310:35;;22400:15;;;;22283:1;22276:9;;;;;22365:12;;;;22247:178;;;22251:3;22474:2;22466:6;22462:15;22456:22;22434:44;;22501:3;22497:8;22487:18;;22567:2;22555:9;22550:3;22546:19;22542:28;22536:3;22525:9;22521:19;22514:57;22594:49;22639:3;22623:14;22594:49;:::i;:::-;22580:63;;;;;22692:2;22684:6;22680:15;22674:22;22761:2;22749:9;22741:6;22737:22;22733:31;22727:3;22716:9;22712:19;22705:60;22788:40;22821:6;22805:14;22788:40;:::i;:::-;22774:54;;;;22877:2;22869:6;22865:15;22859:22;22890:52;22937:3;22926:9;22922:19;22906:14;2101:13;2094:21;2082:34;;2031:91;22890:52;-1:-1:-1;22959:6:1;21427:1544;-1:-1:-1;;;;;;21427:1544:1:o;22976:219::-;23125:2;23114:9;23107:21;23088:4;23145:44;23185:2;23174:9;23170:18;23162:6;23145:44;:::i
Swarm Source
ipfs://17c261cafae263a4586b1edaf080b482e7b68d49dec4e07e1ad79bea50732487
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Validator ID :
0 FTM
Amount Staked
0
Amount Delegated
0
Staking Total
0
Staking Start Epoch
0
Staking Start Time
0
Proof of Importance
0
Origination Score
0
Validation Score
0
Active
0
Online
0
Downtime
0 s
Address | Amount | claimed Rewards | Created On Epoch | Created On |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.