Source Code
Latest 25 from a total of 180 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Panic | 139650055 | 187 days ago | IN | 0 ETH | 0.00000279829 | ||||
| Harvest | 128572406 | 443 days ago | IN | 0 ETH | 0.000000173665 | ||||
| Harvest | 128314126 | 449 days ago | IN | 0 ETH | 0.000001781775 | ||||
| Harvest | 127106339 | 477 days ago | IN | 0 ETH | 0.00000168953 | ||||
| Harvest | 126958272 | 481 days ago | IN | 0 ETH | 0.000000093916 | ||||
| Harvest | 126890124 | 482 days ago | IN | 0 ETH | 0.000000082631 | ||||
| Harvest | 126815748 | 484 days ago | IN | 0 ETH | 0.000000493883 | ||||
| Harvest | 126779568 | 485 days ago | IN | 0 ETH | 0.00000047675 | ||||
| Harvest | 126553843 | 490 days ago | IN | 0 ETH | 0.000000453604 | ||||
| Harvest | 126340970 | 495 days ago | IN | 0 ETH | 0.00000057887 | ||||
| Harvest | 126337576 | 495 days ago | IN | 0 ETH | 0.000001783844 | ||||
| Harvest | 126042060 | 502 days ago | IN | 0 ETH | 0.000000225778 | ||||
| Harvest | 126005074 | 503 days ago | IN | 0 ETH | 0.000000617526 | ||||
| Harvest | 125819460 | 507 days ago | IN | 0 ETH | 0.00000062758 | ||||
| Harvest | 125816730 | 507 days ago | IN | 0 ETH | 0.000000884121 | ||||
| Harvest | 125699975 | 510 days ago | IN | 0 ETH | 0.000000416516 | ||||
| Harvest | 125698488 | 510 days ago | IN | 0 ETH | 0.000000273874 | ||||
| Harvest | 125697483 | 510 days ago | IN | 0 ETH | 0.000000361722 | ||||
| Harvest | 125695956 | 510 days ago | IN | 0 ETH | 0.000000757394 | ||||
| Harvest | 125651246 | 511 days ago | IN | 0 ETH | 0.000061781131 | ||||
| Harvest | 125591635 | 512 days ago | IN | 0 ETH | 0.000004263314 | ||||
| Harvest | 125524881 | 514 days ago | IN | 0 ETH | 0.000000320735 | ||||
| Harvest | 125523485 | 514 days ago | IN | 0 ETH | 0.000000306539 | ||||
| Harvest | 125519494 | 514 days ago | IN | 0 ETH | 0.000000132454 | ||||
| Harvest | 125517290 | 514 days ago | IN | 0 ETH | 0.000000246478 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 107537072 | 930 days ago | 0 ETH | ||||
| 107537072 | 930 days ago | 0 ETH | ||||
| 107537072 | 930 days ago | 0 ETH | ||||
| 107537072 | 930 days ago | 0 ETH | ||||
| 107537072 | 930 days ago | 0 ETH | ||||
| 107537072 | 930 days ago | 0 ETH | ||||
| 107537072 | 930 days ago | 0 ETH | ||||
| 107537072 | 930 days ago | 0 ETH | ||||
| 107537072 | 930 days ago | 0 ETH | ||||
| 107537072 | 930 days ago | 0 ETH | ||||
| 107537072 | 930 days ago | 0 ETH | ||||
| 107537072 | 930 days ago | 0 ETH | ||||
| 107537072 | 930 days ago | 0 ETH | ||||
| 107537072 | 930 days ago | 0 ETH | ||||
| 107537072 | 930 days ago | 0 ETH | ||||
| 107537072 | 930 days ago | 0 ETH | ||||
| 107537072 | 930 days ago | 0 ETH | ||||
| 107537072 | 930 days ago | 0 ETH | ||||
| 107537072 | 930 days ago | 0 ETH | ||||
| 107537072 | 930 days ago | 0 ETH | ||||
| 107537072 | 930 days ago | 0 ETH | ||||
| 107537072 | 930 days ago | 0 ETH | ||||
| 107537072 | 930 days ago | 0 ETH | ||||
| 107537072 | 930 days ago | 0 ETH | ||||
| 107537072 | 930 days ago | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
StrategyCurveLPUniV3Router
Compiler Version
v0.8.15+commit.e14f2714
Contract Source Code (Solidity)
/**
*Submitted for verification at optimistic.etherscan.io on 2023-03-29
*/
// SPDX-License-Identifier: MIT
// File: @openzeppelin-4/contracts/token/ERC20/IERC20.sol
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
// File: @openzeppelin-4/contracts/token/ERC20/extensions/IERC20Metadata.sol
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
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-4/contracts/utils/Context.sol
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
// File: @openzeppelin-4/contracts/token/ERC20/ERC20.sol
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)
pragma solidity ^0.8.0;
/**
* @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:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, 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}.
*
* NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, 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}.
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
* - the caller must have allowance for ``from``'s tokens of at least
* `amount`.
*/
function transferFrom(
address from,
address to,
uint256 amount
) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, 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) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, 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) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
/**
* @dev Moves `amount` of tokens from `from` to `to`.
*
* 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:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
*/
function _transfer(
address from,
address to,
uint256 amount
) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
}
_balances[to] += amount;
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, 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 Updates `owner` s allowance for `spender` based on spent `amount`.
*
* Does not update the allowance amount in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Might emit an {Approval} event.
*/
function _spendAllowance(
address owner,
address spender,
uint256 amount
) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - 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-4/contracts/token/ERC20/extensions/draft-IERC20Permit.sol
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
// File: @openzeppelin-4/contracts/utils/Address.sol
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
// File: @openzeppelin-4/contracts/token/ERC20/utils/SafeERC20.sol
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @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: contracts/BIFI/interfaces/common/IUniswapRouterV3.sol
pragma solidity ^0.8.0;
interface IUniswapRouterV3 {
struct ExactInputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 amountIn;
uint256 amountOutMinimum;
uint160 sqrtPriceLimitX96;
}
/// @notice Swaps `amountIn` of one token for as much as possible of another token
/// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata
/// @return amountOut The amount of the received token
function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);
struct ExactInputParams {
bytes path;
address recipient;
uint256 amountIn;
uint256 amountOutMinimum;
}
/// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path
/// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata
/// @return amountOut The amount of the received token
function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);
struct ExactOutputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 amountOut;
uint256 amountInMaximum;
uint160 sqrtPriceLimitX96;
}
/// @notice Swaps as little as possible of one token for `amountOut` of another token
/// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata
/// @return amountIn The amount of the input token
function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn);
struct ExactOutputParams {
bytes path;
address recipient;
uint256 amountOut;
uint256 amountInMaximum;
}
/// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed)
/// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata
/// @return amountIn The amount of the input token
function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn);
}
// File: contracts/BIFI/interfaces/common/IWrappedNative.sol
pragma solidity >=0.6.0 <0.9.0;
interface IWrappedNative {
function deposit() external payable;
function withdraw(uint256 wad) external;
}
// File: contracts/BIFI/interfaces/curve/ICurveSwap.sol
pragma solidity >=0.6.0;
interface ICurveSwap {
function remove_liquidity_one_coin(uint256 token_amount, int128 i, uint256 min_amount) external;
function calc_withdraw_one_coin(uint256 tokenAmount, int128 i) external view returns (uint256);
function coins(uint256 arg0) external view returns (address);
function add_liquidity(uint256[2] memory amounts, uint256 min_mint_amount) external payable;
function add_liquidity(uint256[2] memory amounts, uint256 min_mint_amount, bool _use_underlying) external;
function add_liquidity(address _pool, uint256[2] memory amounts, uint256 min_mint_amount) external;
function add_liquidity(uint256[3] memory amounts, uint256 min_mint_amount) external payable;
function add_liquidity(uint256[3] memory amounts, uint256 min_mint_amount, bool _use_underlying) external payable;
function add_liquidity(address _pool, uint256[3] memory amounts, uint256 min_mint_amount) external payable;
function add_liquidity(uint256[4] memory amounts, uint256 min_mint_amount) external payable;
function add_liquidity(address _pool, uint256[4] memory amounts, uint256 min_mint_amount) external payable;
function add_liquidity(uint256[5] memory amounts, uint256 min_mint_amount) external payable;
function add_liquidity(address _pool, uint256[5] memory amounts, uint256 min_mint_amount) external payable;
function add_liquidity(uint256[6] memory amounts, uint256 min_mint_amount) external payable;
function add_liquidity(address _pool, uint256[6] memory amounts, uint256 min_mint_amount) external payable;
function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external;
}
// File: contracts/BIFI/interfaces/curve/IGaugeFactory.sol
pragma solidity >=0.6.0;
interface IGaugeFactory {
function mint(address _gauge) external;
}
// File: contracts/BIFI/interfaces/curve/IRewardsGauge.sol
pragma solidity >=0.6.0 <0.9.0;
interface IRewardsGauge {
function balanceOf(address account) external view returns (uint256);
function claimable_reward(address _addr, address _token) external view returns (uint256);
function claim_rewards(address _addr) external;
function deposit(uint256 _value) external;
function withdraw(uint256 _value) external;
function reward_contract() external view returns (address);
}
// File: @openzeppelin-4/contracts/access/Ownable.sol
// OpenZeppelin Contracts (last updated v4.7.0) (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 Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
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-4/contracts/security/Pausable.sol
// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
constructor() {
_paused = false;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
_requireNotPaused();
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
_requirePaused();
_;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Throws if the contract is paused.
*/
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
// File: contracts/BIFI/interfaces/common/IFeeConfig.sol
pragma solidity ^0.8.0;
interface IFeeConfig {
struct FeeCategory {
uint256 total;
uint256 beefy;
uint256 call;
uint256 strategist;
string label;
bool active;
}
struct AllFees {
FeeCategory performance;
uint256 deposit;
uint256 withdraw;
}
function getFees(address strategy) external view returns (FeeCategory memory);
function stratFeeId(address strategy) external view returns (uint256);
function setStratFeeId(uint256 feeId) external;
}
// File: contracts/BIFI/strategies/Common/StratFeeManager.sol
pragma solidity ^0.8.0;
contract StratFeeManager is Ownable, Pausable {
struct CommonAddresses {
address vault;
address unirouter;
address keeper;
address strategist;
address beefyFeeRecipient;
address beefyFeeConfig;
}
// common addresses for the strategy
address public vault;
address public unirouter;
address public keeper;
address public strategist;
address public beefyFeeRecipient;
IFeeConfig public beefyFeeConfig;
uint256 constant DIVISOR = 1 ether;
uint256 constant public WITHDRAWAL_FEE_CAP = 50;
uint256 constant public WITHDRAWAL_MAX = 10000;
uint256 internal withdrawalFee = 10;
event SetStratFeeId(uint256 feeId);
event SetWithdrawalFee(uint256 withdrawalFee);
event SetVault(address vault);
event SetUnirouter(address unirouter);
event SetKeeper(address keeper);
event SetStrategist(address strategist);
event SetBeefyFeeRecipient(address beefyFeeRecipient);
event SetBeefyFeeConfig(address beefyFeeConfig);
constructor(
CommonAddresses memory _commonAddresses
) {
vault = _commonAddresses.vault;
unirouter = _commonAddresses.unirouter;
keeper = _commonAddresses.keeper;
strategist = _commonAddresses.strategist;
beefyFeeRecipient = _commonAddresses.beefyFeeRecipient;
beefyFeeConfig = IFeeConfig(_commonAddresses.beefyFeeConfig);
}
// checks that caller is either owner or keeper.
modifier onlyManager() {
require(msg.sender == owner() || msg.sender == keeper, "!manager");
_;
}
// fetch fees from config contract
function getFees() internal view returns (IFeeConfig.FeeCategory memory) {
return beefyFeeConfig.getFees(address(this));
}
// fetch fees from config contract and dynamic deposit/withdraw fees
function getAllFees() external view returns (IFeeConfig.AllFees memory) {
return IFeeConfig.AllFees(getFees(), depositFee(), withdrawFee());
}
function getStratFeeId() external view returns (uint256) {
return beefyFeeConfig.stratFeeId(address(this));
}
function setStratFeeId(uint256 _feeId) external onlyManager {
beefyFeeConfig.setStratFeeId(_feeId);
emit SetStratFeeId(_feeId);
}
// adjust withdrawal fee
function setWithdrawalFee(uint256 _fee) public onlyManager {
require(_fee <= WITHDRAWAL_FEE_CAP, "!cap");
withdrawalFee = _fee;
emit SetWithdrawalFee(_fee);
}
// set new vault (only for strategy upgrades)
function setVault(address _vault) external onlyOwner {
vault = _vault;
emit SetVault(_vault);
}
// set new unirouter
function setUnirouter(address _unirouter) external onlyOwner {
unirouter = _unirouter;
emit SetUnirouter(_unirouter);
}
// set new keeper to manage strat
function setKeeper(address _keeper) external onlyManager {
keeper = _keeper;
emit SetKeeper(_keeper);
}
// set new strategist address to receive strat fees
function setStrategist(address _strategist) external {
require(msg.sender == strategist, "!strategist");
strategist = _strategist;
emit SetStrategist(_strategist);
}
// set new beefy fee address to receive beefy fees
function setBeefyFeeRecipient(address _beefyFeeRecipient) external onlyOwner {
beefyFeeRecipient = _beefyFeeRecipient;
emit SetBeefyFeeRecipient(_beefyFeeRecipient);
}
// set new fee config address to fetch fees
function setBeefyFeeConfig(address _beefyFeeConfig) external onlyOwner {
beefyFeeConfig = IFeeConfig(_beefyFeeConfig);
emit SetBeefyFeeConfig(_beefyFeeConfig);
}
function depositFee() public virtual view returns (uint256) {
return 0;
}
function withdrawFee() public virtual view returns (uint256) {
return paused() ? 0 : withdrawalFee;
}
function beforeDeposit() external virtual {}
}
// File: contracts/BIFI/utils/IGasPrice.sol
pragma solidity >=0.6.0 <0.9.0;
interface IGasPrice {
function maxGasPrice() external returns (uint);
}
// File: contracts/BIFI/utils/GasFeeThrottler.sol
pragma solidity ^0.8.0;
contract GasFeeThrottler {
bool public shouldGasThrottle = true;
address public gasprice = address(0xA43509661141F254F54D9A326E8Ec851A0b95307);
modifier gasThrottle() {
if (shouldGasThrottle && Address.isContract(gasprice)) {
require(tx.gasprice <= IGasPrice(gasprice).maxGasPrice(), "gas is too high!");
}
_;
}
}
// File: contracts/BIFI/utils/BytesLib.sol
/*
* @title Solidity Bytes Arrays Utils
* @author Gonçalo Sá <[email protected]>
*
* @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.
* The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.
*/
pragma solidity >=0.8.0 <0.9.0;
library BytesLib {
function concat(
bytes memory _preBytes,
bytes memory _postBytes
)
internal
pure
returns (bytes memory)
{
bytes memory tempBytes;
assembly {
// Get a location of some free memory and store it in tempBytes as
// Solidity does for memory variables.
tempBytes := mload(0x40)
// Store the length of the first bytes array at the beginning of
// the memory for tempBytes.
let length := mload(_preBytes)
mstore(tempBytes, length)
// Maintain a memory counter for the current write location in the
// temp bytes array by adding the 32 bytes for the array length to
// the starting location.
let mc := add(tempBytes, 0x20)
// Stop copying when the memory counter reaches the length of the
// first bytes array.
let end := add(mc, length)
for {
// Initialize a copy counter to the start of the _preBytes data,
// 32 bytes into its memory.
let cc := add(_preBytes, 0x20)
} lt(mc, end) {
// Increase both counters by 32 bytes each iteration.
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
// Write the _preBytes data into the tempBytes memory 32 bytes
// at a time.
mstore(mc, mload(cc))
}
// Add the length of _postBytes to the current length of tempBytes
// and store it as the new length in the first 32 bytes of the
// tempBytes memory.
length := mload(_postBytes)
mstore(tempBytes, add(length, mload(tempBytes)))
// Move the memory counter back from a multiple of 0x20 to the
// actual end of the _preBytes data.
mc := end
// Stop copying when the memory counter reaches the new combined
// length of the arrays.
end := add(mc, length)
for {
let cc := add(_postBytes, 0x20)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
// Update the free-memory pointer by padding our last write location
// to 32 bytes: add 31 bytes to the end of tempBytes to move to the
// next 32 byte block, then round down to the nearest multiple of
// 32. If the sum of the length of the two arrays is zero then add
// one before rounding down to leave a blank 32 bytes (the length block with 0).
mstore(0x40, and(
add(add(end, iszero(add(length, mload(_preBytes)))), 31),
not(31) // Round down to the nearest 32 bytes.
))
}
return tempBytes;
}
function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {
assembly {
// Read the first 32 bytes of _preBytes storage, which is the length
// of the array. (We don't need to use the offset into the slot
// because arrays use the entire slot.)
let fslot := sload(_preBytes.slot)
// Arrays of 31 bytes or less have an even value in their slot,
// while longer arrays have an odd value. The actual length is
// the slot divided by two for odd values, and the lowest order
// byte divided by two for even values.
// If the slot is even, bitwise and the slot with 255 and divide by
// two to get the length. If the slot is odd, bitwise and the slot
// with -1 and divide by two.
let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
let mlength := mload(_postBytes)
let newlength := add(slength, mlength)
// slength can contain both the length and contents of the array
// if length < 32 bytes so let's prepare for that
// v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
switch add(lt(slength, 32), lt(newlength, 32))
case 2 {
// Since the new array still fits in the slot, we just need to
// update the contents of the slot.
// uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length
sstore(
_preBytes.slot,
// all the modifications to the slot are inside this
// next block
add(
// we can just add to the slot contents because the
// bytes we want to change are the LSBs
fslot,
add(
mul(
div(
// load the bytes from memory
mload(add(_postBytes, 0x20)),
// zero all bytes to the right
exp(0x100, sub(32, mlength))
),
// and now shift left the number of bytes to
// leave space for the length in the slot
exp(0x100, sub(32, newlength))
),
// increase length by the double of the memory
// bytes length
mul(mlength, 2)
)
)
)
}
case 1 {
// The stored value fits in the slot, but the combined value
// will exceed it.
// get the keccak hash to get the contents of the array
mstore(0x0, _preBytes.slot)
let sc := add(keccak256(0x0, 0x20), div(slength, 32))
// save new length
sstore(_preBytes.slot, add(mul(newlength, 2), 1))
// The contents of the _postBytes array start 32 bytes into
// the structure. Our first read should obtain the `submod`
// bytes that can fit into the unused space in the last word
// of the stored array. To get this, we read 32 bytes starting
// from `submod`, so the data we read overlaps with the array
// contents by `submod` bytes. Masking the lowest-order
// `submod` bytes allows us to add that value directly to the
// stored value.
let submod := sub(32, slength)
let mc := add(_postBytes, submod)
let end := add(_postBytes, mlength)
let mask := sub(exp(0x100, submod), 1)
sstore(
sc,
add(
and(
fslot,
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
),
and(mload(mc), mask)
)
)
for {
mc := add(mc, 0x20)
sc := add(sc, 1)
} lt(mc, end) {
sc := add(sc, 1)
mc := add(mc, 0x20)
} {
sstore(sc, mload(mc))
}
mask := exp(0x100, sub(mc, end))
sstore(sc, mul(div(mload(mc), mask), mask))
}
default {
// get the keccak hash to get the contents of the array
mstore(0x0, _preBytes.slot)
// Start copying to the last used word of the stored array.
let sc := add(keccak256(0x0, 0x20), div(slength, 32))
// save new length
sstore(_preBytes.slot, add(mul(newlength, 2), 1))
// Copy over the first `submod` bytes of the new data as in
// case 1 above.
let slengthmod := mod(slength, 32)
let mlengthmod := mod(mlength, 32)
let submod := sub(32, slengthmod)
let mc := add(_postBytes, submod)
let end := add(_postBytes, mlength)
let mask := sub(exp(0x100, submod), 1)
sstore(sc, add(sload(sc), and(mload(mc), mask)))
for {
sc := add(sc, 1)
mc := add(mc, 0x20)
} lt(mc, end) {
sc := add(sc, 1)
mc := add(mc, 0x20)
} {
sstore(sc, mload(mc))
}
mask := exp(0x100, sub(mc, end))
sstore(sc, mul(div(mload(mc), mask), mask))
}
}
}
function slice(
bytes memory _bytes,
uint256 _start,
uint256 _length
)
internal
pure
returns (bytes memory)
{
require(_length + 31 >= _length, "slice_overflow");
require(_bytes.length >= _start + _length, "slice_outOfBounds");
bytes memory tempBytes;
assembly {
switch iszero(_length)
case 0 {
// Get a location of some free memory and store it in tempBytes as
// Solidity does for memory variables.
tempBytes := mload(0x40)
// The first word of the slice result is potentially a partial
// word read from the original array. To read it, we calculate
// the length of that partial word and start copying that many
// bytes into the array. The first word we copy will start with
// data we don't care about, but the last `lengthmod` bytes will
// land at the beginning of the contents of the new array. When
// we're done copying, we overwrite the full first word with
// the actual length of the slice.
let lengthmod := and(_length, 31)
// The multiplication in the next line is necessary
// because when slicing multiples of 32 bytes (lengthmod == 0)
// the following copy loop was copying the origin's length
// and then ending prematurely not copying everything it should.
let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
let end := add(mc, _length)
for {
// The multiplication in the next line has the same exact purpose
// as the one above.
let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
mstore(tempBytes, _length)
//update free-memory pointer
//allocating the array padded to 32 bytes like the compiler does now
mstore(0x40, and(add(mc, 31), not(31)))
}
//if we want a zero-length slice let's just return a zero-length array
default {
tempBytes := mload(0x40)
//zero out the 32 bytes slice we are about to return
//we need to do it because Solidity does not garbage collect
mstore(tempBytes, 0)
mstore(0x40, add(tempBytes, 0x20))
}
}
return tempBytes;
}
function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {
require(_bytes.length >= _start + 20, "toAddress_outOfBounds");
address tempAddress;
assembly {
tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
}
return tempAddress;
}
function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {
require(_bytes.length >= _start + 1 , "toUint8_outOfBounds");
uint8 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x1), _start))
}
return tempUint;
}
function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {
require(_bytes.length >= _start + 2, "toUint16_outOfBounds");
uint16 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x2), _start))
}
return tempUint;
}
function toUint24(bytes memory _bytes, uint256 _start) internal pure returns (uint24) {
require(_start + 3 >= _start, 'toUint24_overflow');
require(_bytes.length >= _start + 3, 'toUint24_outOfBounds');
uint24 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x3), _start))
}
return tempUint;
}
function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {
require(_bytes.length >= _start + 4, "toUint32_outOfBounds");
uint32 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x4), _start))
}
return tempUint;
}
function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {
require(_bytes.length >= _start + 8, "toUint64_outOfBounds");
uint64 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x8), _start))
}
return tempUint;
}
function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {
require(_bytes.length >= _start + 12, "toUint96_outOfBounds");
uint96 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0xc), _start))
}
return tempUint;
}
function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {
require(_bytes.length >= _start + 16, "toUint128_outOfBounds");
uint128 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x10), _start))
}
return tempUint;
}
function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {
require(_bytes.length >= _start + 32, "toUint256_outOfBounds");
uint256 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x20), _start))
}
return tempUint;
}
function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {
require(_bytes.length >= _start + 32, "toBytes32_outOfBounds");
bytes32 tempBytes32;
assembly {
tempBytes32 := mload(add(add(_bytes, 0x20), _start))
}
return tempBytes32;
}
function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {
bool success = true;
assembly {
let length := mload(_preBytes)
// if lengths don't match the arrays are not equal
switch eq(length, mload(_postBytes))
case 1 {
// cb is a circuit breaker in the for loop since there's
// no said feature for inline assembly loops
// cb = 1 - don't breaker
// cb = 0 - break
let cb := 1
let mc := add(_preBytes, 0x20)
let end := add(mc, length)
for {
let cc := add(_postBytes, 0x20)
// the next line is the loop condition:
// while(uint256(mc < end) + cb == 2)
} eq(add(lt(mc, end), cb), 2) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
// if any of these checks fails then arrays are not equal
if iszero(eq(mload(mc), mload(cc))) {
// unsuccess:
success := 0
cb := 0
}
}
}
default {
// unsuccess:
success := 0
}
}
return success;
}
function equalStorage(
bytes storage _preBytes,
bytes memory _postBytes
)
internal
view
returns (bool)
{
bool success = true;
assembly {
// we know _preBytes_offset is 0
let fslot := sload(_preBytes.slot)
// Decode the length of the stored array like in concatStorage().
let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
let mlength := mload(_postBytes)
// if lengths don't match the arrays are not equal
switch eq(slength, mlength)
case 1 {
// slength can contain both the length and contents of the array
// if length < 32 bytes so let's prepare for that
// v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
if iszero(iszero(slength)) {
switch lt(slength, 32)
case 1 {
// blank the last byte which is the length
fslot := mul(div(fslot, 0x100), 0x100)
if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {
// unsuccess:
success := 0
}
}
default {
// cb is a circuit breaker in the for loop since there's
// no said feature for inline assembly loops
// cb = 1 - don't breaker
// cb = 0 - break
let cb := 1
// get the keccak hash to get the contents of the array
mstore(0x0, _preBytes.slot)
let sc := keccak256(0x0, 0x20)
let mc := add(_postBytes, 0x20)
let end := add(mc, mlength)
// the next line is the loop condition:
// while(uint256(mc < end) + cb == 2)
for {} eq(add(lt(mc, end), cb), 2) {
sc := add(sc, 1)
mc := add(mc, 0x20)
} {
if iszero(eq(sload(sc), mload(mc))) {
// unsuccess:
success := 0
cb := 0
}
}
}
}
}
default {
// unsuccess:
success := 0
}
}
return success;
}
}
// File: contracts/BIFI/utils/Path.sol
pragma solidity >=0.6.0;
/// @title Functions for manipulating path data for multihop swaps
library Path {
using BytesLib for bytes;
/// @dev The length of the bytes encoded address
uint256 private constant ADDR_SIZE = 20;
/// @dev The length of the bytes encoded fee
uint256 private constant FEE_SIZE = 3;
/// @dev The offset of a single token address and pool fee
uint256 private constant NEXT_OFFSET = ADDR_SIZE + FEE_SIZE;
/// @dev The offset of an encoded pool key
uint256 private constant POP_OFFSET = NEXT_OFFSET + ADDR_SIZE;
/// @dev The minimum length of an encoding that contains 2 or more pools
uint256 private constant MULTIPLE_POOLS_MIN_LENGTH = POP_OFFSET + NEXT_OFFSET;
/// @notice Returns true iff the path contains two or more pools
/// @param path The encoded swap path
/// @return True if path contains two or more pools, otherwise false
function hasMultiplePools(bytes memory path) internal pure returns (bool) {
return path.length >= MULTIPLE_POOLS_MIN_LENGTH;
}
/// @notice Returns the number of pools in the path
/// @param path The encoded swap path
/// @return The number of pools in the path
function numPools(bytes memory path) internal pure returns (uint256) {
// Ignore the first token address. From then on every fee and token offset indicates a pool.
return ((path.length - ADDR_SIZE) / NEXT_OFFSET);
}
/// @notice Decodes the first pool in path
/// @param path The bytes encoded swap path
/// @return tokenA The first token of the given pool
/// @return tokenB The second token of the given pool
/// @return fee The fee level of the pool
function decodeFirstPool(bytes memory path)
internal
pure
returns (
address tokenA,
address tokenB,
uint24 fee
)
{
tokenA = path.toAddress(0);
fee = path.toUint24(ADDR_SIZE);
tokenB = path.toAddress(NEXT_OFFSET);
}
/// @notice Gets the segment corresponding to the first pool in the path
/// @param path The bytes encoded swap path
/// @return The segment containing all data necessary to target the first pool in the path
function getFirstPool(bytes memory path) internal pure returns (bytes memory) {
return path.slice(0, POP_OFFSET);
}
/// @notice Skips a token + fee element from the buffer and returns the remainder
/// @param path The swap path
/// @return The remaining token + fee elements in the path
function skipToken(bytes memory path) internal pure returns (bytes memory) {
return path.slice(NEXT_OFFSET, path.length - NEXT_OFFSET);
}
}
// File: contracts/BIFI/interfaces/common/IKyberElastic.sol
pragma solidity ^0.8.0;
interface IKyberElastic {
struct ExactInputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 deadline;
uint256 amountIn;
uint256 minAmountOut;
uint160 limitSqrtP;
}
/// @notice Swaps `amountIn` of one token for as much as possible of another token
/// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata
/// @return amountOut The amount of the received token
function swapExactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);
struct ExactInputParams {
bytes path;
address recipient;
uint256 deadline;
uint256 amountIn;
uint256 minAmountOut;
}
/// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path
/// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata
/// @return amountOut The amount of the received token
function swapExactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);
struct ExactOutputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 deadline;
uint256 amountOut;
uint256 maxAmountIn;
uint160 limitSqrtP;
}
/// @notice Swaps as little as possible of one token for `amountOut` of another token
/// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata
/// @return amountIn The amount of the input token
function swapExactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn);
struct ExactOutputParams {
bytes path;
address recipient;
uint256 deadline;
uint256 amountOut;
uint256 maxAmountIn;
}
/// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed)
/// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata
/// @return amountIn The amount of the input token
function swapExactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn);
}
// File: contracts/BIFI/interfaces/common/IUniswapRouterV3WithDeadline.sol
pragma solidity >=0.6.0;
pragma experimental ABIEncoderV2;
interface IUniswapRouterV3WithDeadline {
struct ExactInputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 deadline;
uint256 amountIn;
uint256 amountOutMinimum;
uint160 sqrtPriceLimitX96;
}
/// @notice Swaps `amountIn` of one token for as much as possible of another token
/// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata
/// @return amountOut The amount of the received token
function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);
struct ExactInputParams {
bytes path;
address recipient;
uint256 deadline;
uint256 amountIn;
uint256 amountOutMinimum;
}
/// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path
/// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata
/// @return amountOut The amount of the received token
function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);
struct ExactOutputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 deadline;
uint256 amountOut;
uint256 amountInMaximum;
uint160 sqrtPriceLimitX96;
}
/// @notice Swaps as little as possible of one token for `amountOut` of another token
/// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata
/// @return amountIn The amount of the input token
function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn);
struct ExactOutputParams {
bytes path;
address recipient;
uint256 deadline;
uint256 amountOut;
uint256 amountInMaximum;
}
/// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed)
/// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata
/// @return amountIn The amount of the input token
function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn);
}
// File: contracts/BIFI/utils/UniV3Actions.sol
pragma solidity ^0.8.0;
library UniV3Actions {
// kyber V3 swap
function kyberSwap(address _router, bytes memory _path, uint256 _amount) internal returns (uint256 amountOut) {
IKyberElastic.ExactInputParams memory swapParams = IKyberElastic.ExactInputParams({
path: _path,
recipient: address(this),
deadline: block.timestamp,
amountIn: _amount,
minAmountOut: 0
});
return IKyberElastic(_router).swapExactInput(swapParams);
}
// Uniswap V3 swap
function swapV3(address _router, bytes memory _path, uint256 _amount) internal returns (uint256 amountOut) {
IUniswapRouterV3.ExactInputParams memory swapParams = IUniswapRouterV3.ExactInputParams({
path: _path,
recipient: address(this),
amountIn: _amount,
amountOutMinimum: 0
});
return IUniswapRouterV3(_router).exactInput(swapParams);
}
// Uniswap V3 swap with deadline
function swapV3WithDeadline(address _router, bytes memory _path, uint256 _amount) internal returns (uint256 amountOut) {
IUniswapRouterV3WithDeadline.ExactInputParams memory swapParams = IUniswapRouterV3WithDeadline.ExactInputParams({
path: _path,
recipient: address(this),
deadline: block.timestamp,
amountIn: _amount,
amountOutMinimum: 0
});
return IUniswapRouterV3WithDeadline(_router).exactInput(swapParams);
}
// Uniswap V3 swap with deadline
function swapV3WithDeadline(address _router, bytes memory _path, uint256 _amount, address _to) internal returns (uint256 amountOut) {
IUniswapRouterV3WithDeadline.ExactInputParams memory swapParams = IUniswapRouterV3WithDeadline.ExactInputParams({
path: _path,
recipient: _to,
deadline: block.timestamp,
amountIn: _amount,
amountOutMinimum: 0
});
return IUniswapRouterV3WithDeadline(_router).exactInput(swapParams);
}
}
// File: contracts/BIFI/strategies/Curve/StrategyCurveLPUniV3Router.sol
pragma solidity ^0.8.0;
contract StrategyCurveLPUniV3Router is StratFeeManager, GasFeeThrottler {
using Path for bytes;
using SafeERC20 for IERC20;
// Tokens used
address public want; // curve lpToken
address public crv;
address public native;
address public depositToken;
// Third party contracts
address public gaugeFactory;
address public rewardsGauge;
address public pool;
uint public poolSize;
uint public depositIndex;
bool public useUnderlying;
bool public useMetapool;
// Uniswap V3 routes
bytes public crvToNativePath;
bytes public nativeToDepositPath;
struct Reward {
address token;
bytes toNativePath;
uint minAmount; // minimum amount to be swapped to native
}
Reward[] public rewards;
// if no CRV rewards yet, can enable later with custom router
bool public crvEnabled = true;
address public crvRouter;
// if depositToken should be sent as unwrapped native
bool public depositNative;
bool public harvestOnDeposit;
uint256 public lastHarvest;
event StratHarvest(address indexed harvester, uint256 wantHarvested, uint256 tvl);
event Deposit(uint256 tvl);
event Withdraw(uint256 tvl);
event ChargedFees(uint256 callFees, uint256 beefyFees, uint256 strategistFees);
constructor(
address _want,
address _gaugeFactory,
address _gauge,
address _pool,
uint[] memory _params, // [poolSize, depositIndex, useUnderlying, useMetapool]
bytes[] memory _paths, // [crvToNativePath, nativeToDepositPath]
CommonAddresses memory _commonAddresses
) StratFeeManager(_commonAddresses) {
want = _want;
gaugeFactory = _gaugeFactory;
rewardsGauge = _gauge;
pool = _pool;
poolSize = _params[0];
depositIndex = _params[1];
useUnderlying = _params[2] > 0;
useMetapool = _params[3] > 0;
// crvToNative
address[] memory route = _pathToRoute(_paths[0]);
crv = route[0];
native = route[route.length - 1];
crvToNativePath = _paths[0];
crvRouter = unirouter;
// nativeToDeposit
route = _pathToRoute(_paths[1]);
require(route[0] == native, '_nativeToDeposit[0] != native');
depositToken = route[route.length - 1];
nativeToDepositPath = _paths[1];
if (gaugeFactory != address(0)) {
harvestOnDeposit = true;
withdrawalFee = 0;
}
_giveAllowances();
}
// puts the funds to work
function deposit() public whenNotPaused {
uint256 wantBal = IERC20(want).balanceOf(address(this));
if (wantBal > 0) {
IRewardsGauge(rewardsGauge).deposit(wantBal);
emit Deposit(balanceOf());
}
}
function withdraw(uint256 _amount) external {
require(msg.sender == vault, "!vault");
uint256 wantBal = IERC20(want).balanceOf(address(this));
if (wantBal < _amount) {
IRewardsGauge(rewardsGauge).withdraw(_amount - wantBal);
wantBal = IERC20(want).balanceOf(address(this));
}
if (wantBal > _amount) {
wantBal = _amount;
}
if (tx.origin != owner() && !paused()) {
uint256 withdrawalFeeAmount = wantBal * withdrawalFee / WITHDRAWAL_MAX;
wantBal = wantBal - withdrawalFeeAmount;
}
IERC20(want).safeTransfer(vault, wantBal);
emit Withdraw(balanceOf());
}
function beforeDeposit() external override {
if (harvestOnDeposit) {
require(msg.sender == vault, "!vault");
_harvest(tx.origin);
}
}
function harvest() external gasThrottle virtual {
_harvest(tx.origin);
}
function harvest(address callFeeRecipient) external gasThrottle virtual {
_harvest(callFeeRecipient);
}
function managerHarvest() external onlyManager {
_harvest(tx.origin);
}
// compounds earnings and charges performance fee
function _harvest(address callFeeRecipient) internal whenNotPaused {
if (gaugeFactory != address(0)) {
IGaugeFactory(gaugeFactory).mint(rewardsGauge);
}
IRewardsGauge(rewardsGauge).claim_rewards(address(this));
swapRewardsToNative();
uint256 nativeBal = IERC20(native).balanceOf(address(this));
if (nativeBal > 0) {
chargeFees(callFeeRecipient);
addLiquidity();
uint256 wantHarvested = balanceOfWant();
deposit();
lastHarvest = block.timestamp;
emit StratHarvest(msg.sender, wantHarvested, balanceOf());
}
}
function _swapV3(bytes memory _path, uint256 _amount) internal returns (uint256 amountOut) {
return UniV3Actions.swapV3WithDeadline(unirouter, _path, _amount);
}
function swapRewardsToNative() internal {
uint256 crvBal = IERC20(crv).balanceOf(address(this));
if (crvEnabled && crvBal > 0) {
UniV3Actions.swapV3WithDeadline(crvRouter, crvToNativePath, crvBal);
}
// extras
for (uint i; i < rewards.length; i++) {
uint bal = IERC20(rewards[i].token).balanceOf(address(this));
if (bal >= rewards[i].minAmount) {
_swapV3(rewards[i].toNativePath, bal);
}
}
}
// performance fees
function chargeFees(address callFeeRecipient) internal {
IFeeConfig.FeeCategory memory fees = getFees();
uint256 nativeBal = IERC20(native).balanceOf(address(this)) * fees.total / DIVISOR;
uint256 callFeeAmount = nativeBal * fees.call / DIVISOR;
IERC20(native).safeTransfer(callFeeRecipient, callFeeAmount);
uint256 beefyFeeAmount = nativeBal * fees.beefy / DIVISOR;
IERC20(native).safeTransfer(beefyFeeRecipient, beefyFeeAmount);
uint256 strategistFeeAmount = nativeBal * fees.strategist / DIVISOR;
IERC20(native).safeTransfer(strategist, strategistFeeAmount);
emit ChargedFees(callFeeAmount, beefyFeeAmount, strategistFeeAmount);
}
// Adds liquidity to AMM and gets more LP tokens.
function addLiquidity() internal {
uint256 depositBal;
uint256 depositNativeAmount;
uint256 nativeBal = IERC20(native).balanceOf(address(this));
if (depositToken != native) {
_swapV3(nativeToDepositPath, nativeBal);
depositBal = IERC20(depositToken).balanceOf(address(this));
} else {
depositBal = nativeBal;
if (depositNative) {
depositNativeAmount = nativeBal;
IWrappedNative(native).withdraw(depositNativeAmount);
}
}
if (poolSize == 2) {
uint256[2] memory amounts;
amounts[depositIndex] = depositBal;
if (useUnderlying) ICurveSwap(pool).add_liquidity(amounts, 0, true);
else ICurveSwap(pool).add_liquidity{value: depositNativeAmount}(amounts, 0);
} else if (poolSize == 3) {
uint256[3] memory amounts;
amounts[depositIndex] = depositBal;
if (useUnderlying) ICurveSwap(pool).add_liquidity(amounts, 0, true);
else if (useMetapool) ICurveSwap(pool).add_liquidity(want, amounts, 0);
else ICurveSwap(pool).add_liquidity(amounts, 0);
} else if (poolSize == 4) {
uint256[4] memory amounts;
amounts[depositIndex] = depositBal;
if (useMetapool) ICurveSwap(pool).add_liquidity(want, amounts, 0);
else ICurveSwap(pool).add_liquidity(amounts, 0);
} else if (poolSize == 5) {
uint256[5] memory amounts;
amounts[depositIndex] = depositBal;
ICurveSwap(pool).add_liquidity(amounts, 0);
}
}
function addRewardToken(bytes memory _rewardToNativePath, uint _minAmount) external onlyOwner {
address[] memory _rewardToNativeRoute = _pathToRoute(_rewardToNativePath);
address token = _rewardToNativeRoute[0];
require(token != want, "!want");
require(token != rewardsGauge, "!gauge");
rewards.push(Reward(token, _rewardToNativePath, _minAmount));
IERC20(token).safeApprove(unirouter, 0);
IERC20(token).safeApprove(unirouter, type(uint).max);
}
function resetRewardTokens() external onlyManager {
delete rewards;
}
// calculate the total underlaying 'want' held by the strat.
function balanceOf() public view returns (uint256) {
return balanceOfWant() + balanceOfPool();
}
// it calculates how much 'want' this contract holds.
function balanceOfWant() public view returns (uint256) {
return IERC20(want).balanceOf(address(this));
}
// it calculates how much 'want' the strategy has working in the farm.
function balanceOfPool() public view returns (uint256) {
return IRewardsGauge(rewardsGauge).balanceOf(address(this));
}
function _pathToRoute(bytes memory _path) internal pure returns (address[] memory) {
uint numPools = _path.numPools();
address[] memory route = new address[](numPools + 1);
for (uint i; i < numPools; i++) {
(address tokenA, address tokenB,) = _path.decodeFirstPool();
route[i] = tokenA;
route[i + 1] = tokenB;
_path = _path.skipToken();
}
return route;
}
function crvToNative() external view returns (address[] memory) {
return _pathToRoute(crvToNativePath);
}
function nativeToDeposit() external view returns (address[] memory) {
return _pathToRoute(nativeToDepositPath);
}
function rewardToNative() external view returns (address[] memory) {
return _pathToRoute(rewards[0].toNativePath);
}
function rewardToNative(uint i) external view returns (address[] memory) {
return _pathToRoute(rewards[i].toNativePath);
}
function rewardsLength() external view returns (uint) {
return rewards.length;
}
function setCrvEnabled(bool _enabled) external onlyManager {
crvEnabled = _enabled;
}
function setCrvRoute(address _router, bytes memory _crvToNativePath) external onlyManager {
address[] memory _crvToNative = _pathToRoute(_crvToNativePath);
require(_crvToNative[0] == crv, '!crv');
require(_crvToNative[_crvToNative.length - 1] == native, '!native');
_removeAllowances();
crvToNativePath = _crvToNativePath;
crvRouter = _router;
_giveAllowances();
}
function setDepositNative(bool _depositNative) external onlyOwner {
depositNative = _depositNative;
}
function setHarvestOnDeposit(bool _harvestOnDeposit) external onlyManager {
harvestOnDeposit = _harvestOnDeposit;
if (harvestOnDeposit) {
setWithdrawalFee(0);
} else {
setWithdrawalFee(10);
}
}
// returns rewards unharvested
function rewardsAvailable() public view returns (uint256) {
return IRewardsGauge(rewardsGauge).claimable_reward(address(this), crv);
}
// native reward amount for calling harvest
// NO "view" functions in Uniswap V3 to quote amounts
// Curve rewardsAvailable() also returns 0 most of the time
function callReward() public pure returns (uint256) {
return 0;
}
function setShouldGasThrottle(bool _shouldGasThrottle) external onlyManager {
shouldGasThrottle = _shouldGasThrottle;
}
// called as part of strat migration. Sends all the available funds back to the vault.
function retireStrat() external {
require(msg.sender == vault, "!vault");
IRewardsGauge(rewardsGauge).withdraw(balanceOfPool());
uint256 wantBal = IERC20(want).balanceOf(address(this));
IERC20(want).transfer(vault, wantBal);
}
// pauses deposits and withdraws all funds from third party systems.
function panic() public onlyManager {
pause();
IRewardsGauge(rewardsGauge).withdraw(balanceOfPool());
}
function pause() public onlyManager {
_pause();
_removeAllowances();
}
function unpause() external onlyManager {
_unpause();
_giveAllowances();
deposit();
}
function _giveAllowances() internal {
IERC20(want).safeApprove(rewardsGauge, type(uint).max);
IERC20(native).safeApprove(unirouter, type(uint).max);
IERC20(crv).safeApprove(crvRouter, type(uint).max);
IERC20(depositToken).safeApprove(pool, type(uint).max);
}
function _removeAllowances() internal {
IERC20(want).safeApprove(rewardsGauge, 0);
IERC20(native).safeApprove(unirouter, 0);
IERC20(crv).safeApprove(crvRouter, 0);
IERC20(depositToken).safeApprove(pool, 0);
}
receive () external payable {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_want","type":"address"},{"internalType":"address","name":"_gaugeFactory","type":"address"},{"internalType":"address","name":"_gauge","type":"address"},{"internalType":"address","name":"_pool","type":"address"},{"internalType":"uint256[]","name":"_params","type":"uint256[]"},{"internalType":"bytes[]","name":"_paths","type":"bytes[]"},{"components":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"address","name":"unirouter","type":"address"},{"internalType":"address","name":"keeper","type":"address"},{"internalType":"address","name":"strategist","type":"address"},{"internalType":"address","name":"beefyFeeRecipient","type":"address"},{"internalType":"address","name":"beefyFeeConfig","type":"address"}],"internalType":"struct StratFeeManager.CommonAddresses","name":"_commonAddresses","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"callFees","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"beefyFees","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"strategistFees","type":"uint256"}],"name":"ChargedFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tvl","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"beefyFeeConfig","type":"address"}],"name":"SetBeefyFeeConfig","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"beefyFeeRecipient","type":"address"}],"name":"SetBeefyFeeRecipient","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"keeper","type":"address"}],"name":"SetKeeper","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"feeId","type":"uint256"}],"name":"SetStratFeeId","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"strategist","type":"address"}],"name":"SetStrategist","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"unirouter","type":"address"}],"name":"SetUnirouter","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"vault","type":"address"}],"name":"SetVault","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"withdrawalFee","type":"uint256"}],"name":"SetWithdrawalFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"harvester","type":"address"},{"indexed":false,"internalType":"uint256","name":"wantHarvested","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tvl","type":"uint256"}],"name":"StratHarvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tvl","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"WITHDRAWAL_FEE_CAP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WITHDRAWAL_MAX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_rewardToNativePath","type":"bytes"},{"internalType":"uint256","name":"_minAmount","type":"uint256"}],"name":"addRewardToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"balanceOf","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":"balanceOfWant","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"beefyFeeConfig","outputs":[{"internalType":"contract IFeeConfig","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"beefyFeeRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"beforeDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"callReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"crv","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"crvEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"crvRouter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"crvToNative","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"crvToNativePath","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"depositFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"depositIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"depositNative","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"depositToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gasprice","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gaugeFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllFees","outputs":[{"components":[{"components":[{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"uint256","name":"beefy","type":"uint256"},{"internalType":"uint256","name":"call","type":"uint256"},{"internalType":"uint256","name":"strategist","type":"uint256"},{"internalType":"string","name":"label","type":"string"},{"internalType":"bool","name":"active","type":"bool"}],"internalType":"struct IFeeConfig.FeeCategory","name":"performance","type":"tuple"},{"internalType":"uint256","name":"deposit","type":"uint256"},{"internalType":"uint256","name":"withdraw","type":"uint256"}],"internalType":"struct IFeeConfig.AllFees","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStratFeeId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"callFeeRecipient","type":"address"}],"name":"harvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"harvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"harvestOnDeposit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"keeper","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastHarvest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"managerHarvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"native","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nativeToDeposit","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nativeToDepositPath","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"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":"pool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resetRewardTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"retireStrat","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardToNative","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"i","type":"uint256"}],"name":"rewardToNative","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewards","outputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes","name":"toNativePath","type":"bytes"},{"internalType":"uint256","name":"minAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsAvailable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsGauge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_beefyFeeConfig","type":"address"}],"name":"setBeefyFeeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_beefyFeeRecipient","type":"address"}],"name":"setBeefyFeeRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"setCrvEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_router","type":"address"},{"internalType":"bytes","name":"_crvToNativePath","type":"bytes"}],"name":"setCrvRoute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_depositNative","type":"bool"}],"name":"setDepositNative","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_harvestOnDeposit","type":"bool"}],"name":"setHarvestOnDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_keeper","type":"address"}],"name":"setKeeper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_shouldGasThrottle","type":"bool"}],"name":"setShouldGasThrottle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_feeId","type":"uint256"}],"name":"setStratFeeId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategist","type":"address"}],"name":"setStrategist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_unirouter","type":"address"}],"name":"setUnirouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"setVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setWithdrawalFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shouldGasThrottle","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"strategist","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unirouter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"useMetapool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"useUnderlying","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"want","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
6080604052600a600755600880546001600160a81b03191674a43509661141f254f54d9a326e8ec851a0b95307011790556016805460ff191660011790553480156200004a57600080fd5b50604051620056fa380380620056fa8339810160408190526200006d9162001035565b80620000793362000483565b6000805460ff60a01b191681558151600180546001600160a01b03199081166001600160a01b0393841617909155602084015160028054831691841691909117905560408401516003805483169184169190911790556060840151600480548316918416919091179055608084015160058054831691841691909117905560a0909301516006805485169183169190911790556009805484168b8316179055600d805484168a8316179055600e80548416898316179055600f80549093169087161790915583518491906200015257620001526200115c565b6020026020010151601081905550826001815181106200017657620001766200115c565b60200260200101516011819055506000836002815181106200019c576200019c6200115c565b602002602001015111601260006101000a81548160ff021916908315150217905550600083600381518110620001d657620001d66200115c565b602002602001015111601260016101000a81548160ff021916908315150217905550600062000228836000815181106200021457620002146200115c565b6020026020010151620004d360201b60201c565b9050806000815181106200024057620002406200115c565b6020026020010151600a60006101000a8154816001600160a01b0302191690836001600160a01b0316021790555080600182516200027f919062001188565b815181106200029257620002926200115c565b6020026020010151600b60006101000a8154816001600160a01b0302191690836001600160a01b0316021790555082600081518110620002d657620002d66200115c565b602002602001015160139081620002ee919062001230565b50600254601680546001600160a01b0390921661010002610100600160a81b031990921691909117905582516200033590849060019081106200021457620002146200115c565b600b5481519192506001600160a01b03169082906000906200035b576200035b6200115c565b60200260200101516001600160a01b031614620003bf5760405162461bcd60e51b815260206004820152601d60248201527f5f6e6174697665546f4465706f7369745b305d20213d206e617469766500000060448201526064015b60405180910390fd5b8060018251620003d0919062001188565b81518110620003e357620003e36200115c565b6020026020010151600c60006101000a8154816001600160a01b0302191690836001600160a01b03160217905550826001815181106200042757620004276200115c565b6020026020010151601490816200043f919062001230565b50600d546001600160a01b0316156200046b576016805460ff60b01b1916600160b01b17905560006007555b6200047562000617565b5050505050505050620013e7565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60606000620004ed83620006d360201b620021c51760201c565b90506000620004fe826001620012fc565b6001600160401b0381111562000518576200051862000de8565b60405190808252806020026020018201604052801562000542578160200160208202803683370190505b50905060005b828110156200060f576000806200056a876200070560201b620021eb1760201c565b5091509150818484815181106200058557620005856200115c565b6001600160a01b03909216602092830291909101909101528084620005ac856001620012fc565b81518110620005bf57620005bf6200115c565b60200260200101906001600160a01b031690816001600160a01b031681525050620005f5876200077460201b620022271760201c565b965050508080620006069062001317565b91505062000548565b509392505050565b600e5460095462000644916001600160a01b039182169116600019620007ba602090811b6200225817901c565b600254600b5462000671916001600160a01b039182169116600019620007ba602090811b6200225817901c565b601654600a54620006a4916001600160a01b039182169161010090910416600019620007ba602090811b6200225817901c565b600f54600c54620006d1916001600160a01b039182169116600019620007ba602090811b6200225817901c565b565b6000620006e360036014620012fc565b60148351620006f3919062001188565b620006ff919062001333565b92915050565b6000806000620007256000856200090960201b620023a01790919060201c565b9250620007426014856200098360201b620024051790919060201c565b90506200076b6200075660036014620012fc565b856200090960201b620023a01790919060201c565b91509193909250565b6060620006ff6200078860036014620012fc565b6200079660036014620012fc565b8451620007a4919062001188565b8462000a3f60201b620024b0179092919060201c565b801580620008385750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa15801562000810573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000836919062001356565b155b620008ac5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401620003b6565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091526200090491859162000b5a16565b505050565b600062000918826014620012fc565b835110156200096a5760405162461bcd60e51b815260206004820152601560248201527f746f416464726573735f6f75744f66426f756e647300000000000000000000006044820152606401620003b6565b5001602001516c01000000000000000000000000900490565b60008162000993816003620012fc565b1015620009d75760405162461bcd60e51b8152602060048201526011602482015270746f55696e7432345f6f766572666c6f7760781b6044820152606401620003b6565b620009e4826003620012fc565b8351101562000a365760405162461bcd60e51b815260206004820152601460248201527f746f55696e7432345f6f75744f66426f756e64730000000000000000000000006044820152606401620003b6565b50016003015190565b60608162000a4f81601f620012fc565b101562000a905760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b6044820152606401620003b6565b62000a9c8284620012fc565b8451101562000ae25760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b6044820152606401620003b6565b60608215801562000b03576040519150600082526020820160405262000b4f565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101562000b3e57805183526020928301920162000b24565b5050858452601f01601f1916604052505b5090505b9392505050565b600062000bb6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031662000c3860201b620025bf179092919060201c565b80519091501562000904578080602001905181019062000bd7919062001370565b620009045760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401620003b6565b606062000c49848460008562000c51565b949350505050565b60608247101562000cb45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401620003b6565b6001600160a01b0385163b62000d0d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401620003b6565b600080866001600160a01b0316858760405162000d2b919062001394565b60006040518083038185875af1925050503d806000811462000d6a576040519150601f19603f3d011682016040523d82523d6000602084013e62000d6f565b606091505b50909250905062000d8282828662000d8d565b979650505050505050565b6060831562000d9e57508162000b53565b82511562000daf5782518084602001fd5b8160405162461bcd60e51b8152600401620003b69190620013b2565b80516001600160a01b038116811462000de357600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171562000e295762000e2962000de8565b604052919050565b60006001600160401b0382111562000e4d5762000e4d62000de8565b5060051b60200190565b60005b8381101562000e7457818101518382015260200162000e5a565b8381111562000e84576000848401525b50505050565b6000601f838184011262000e9d57600080fd5b8251602062000eb662000eb08362000e31565b62000dfe565b82815260059290921b8501810191818101908784111562000ed657600080fd5b8287015b8481101562000f785780516001600160401b038082111562000efc5760008081fd5b818a0191508a603f83011262000f125760008081fd5b8582015160408282111562000f2b5762000f2b62000de8565b62000f3e828b01601f1916890162000dfe565b92508183528c8183860101111562000f565760008081fd5b62000f678289850183870162000e57565b505084525091830191830162000eda565b50979650505050505050565b600060c0828403121562000f9757600080fd5b60405160c081016001600160401b038111828210171562000fbc5762000fbc62000de8565b60405290508062000fcd8362000dcb565b815262000fdd6020840162000dcb565b602082015262000ff06040840162000dcb565b6040820152620010036060840162000dcb565b6060820152620010166080840162000dcb565b60808201526200102960a0840162000dcb565b60a08201525092915050565b6000806000806000806000610180888a0312156200105257600080fd5b6200105d8862000dcb565b965060206200106e818a0162000dcb565b96506200107e60408a0162000dcb565b95506200108e60608a0162000dcb565b60808a01519095506001600160401b0380821115620010ac57600080fd5b818b0191508b601f830112620010c157600080fd5b8151620010d262000eb08262000e31565b81815260059190911b8301840190848101908e831115620010f257600080fd5b938501935b828510156200111257845182529385019390850190620010f7565b60a08e015190985094505050808311156200112c57600080fd5b50506200113c8a828b0162000e8a565b9250506200114e8960c08a0162000f84565b905092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000828210156200119d576200119d62001172565b500390565b600181811c90821680620011b757607f821691505b602082108103620011d857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200090457600081815260208120601f850160051c81016020861015620012075750805b601f850160051c820191505b81811015620012285782815560010162001213565b505050505050565b81516001600160401b038111156200124c576200124c62000de8565b62001264816200125d8454620011a2565b84620011de565b602080601f8311600181146200129c5760008415620012835750858301515b600019600386901b1c1916600185901b17855562001228565b600085815260208120601f198616915b82811015620012cd57888601518255948401946001909101908401620012ac565b5085821015620012ec5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000821982111562001312576200131262001172565b500190565b6000600182016200132c576200132c62001172565b5060010190565b6000826200135157634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156200136957600080fd5b5051919050565b6000602082840312156200138357600080fd5b8151801515811462000b5357600080fd5b60008251620013a881846020870162000e57565b9190910192915050565b6020815260008251806020840152620013d381604085016020870162000e57565b601f01601f19169190910160400192915050565b61430380620013f76000396000f3fe60806040526004361061041f5760003560e01c80638cfc02501161021e578063d0e30db011610123578063e941fa78116100ab578063fad4675e1161007a578063fad4675e14610baa578063fb61778714610bca578063fbe7515214610bdf578063fbfa77cf14610bff578063fccf884d14610c1f57600080fd5b8063e941fa7814610b30578063f1a392da14610b45578063f2fde38b14610b5b578063f301af4214610b7b57600080fd5b8063db6b5246116100f2578063db6b524614610aab578063de5b8b2214610acc578063dfbdc43714610ae6578063e4d6cf3014610afb578063e7a7250a14610b1b57600080fd5b8063d0e30db014610a4c578063d801d94614610a61578063d92f3d7314610a76578063da512c3414610a9657600080fd5b8063b20feaaf116101a6578063c1a3d44c11610175578063c1a3d44c146109bd578063c6ddbeeb146109d2578063c7b9d530146109ec578063c89039c514610a0c578063cd80c16714610a2c57600080fd5b8063b20feaaf14610952578063b503ae0014610974578063b7923c6e14610993578063bbb356d5146109a857600080fd5b806397fd323d116101ed57806397fd323d146107315780639f8b5da1146108d8578063a68833e5146108f2578063ac1e502514610912578063aced16611461093257600080fd5b80638cfc0250146108655780638da5cb5b1461087a5780638e145459146108985780638ff4486d146108b857600080fd5b80634700d305116103245780636a4874a1116102ac578063748747e61161027b578063748747e6146107d45780637b898939146107f45780637f1735591461080a5780638456cb591461082f5780638912cb8b1461084457600080fd5b80636a4874a1146107655780636ec232d314610785578063715018a6146107aa578063722713f7146107bf57600080fd5b8063573fef0a116102f3578063573fef0a146106d15780635839b094146106e65780635c975abb1461070657806367a52793146107315780636817031b1461074557600080fd5b80634700d305146106705780634746fb55146106855780634ec18db9146106a557806354518b1a146106bb57600080fd5b80631fe4a686116103a75780633c1deb53116103765780633c1deb53146105ef5780633e55f932146106115780633f4ba83a14610631578063449c27a8146106465780634641257d1461065b57600080fd5b80631fe4a6861461056f578063257ae0de1461058f5780632e1a7d4d146105af5780633930d6b6146105cf57600080fd5b8063106fdbd0116103ee578063106fdbd0146104cc57806311588086146104ec57806311b0b42d1461050f57806316f0115b1461052f5780631f1fcd511461054f57600080fd5b80630d52333c1461042b5780630d6ff380146104685780630e5c011e1461048a5780630e8fbb5a146104ac57600080fd5b3661042657005b600080fd5b34801561043757600080fd5b50600d5461044b906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561047457600080fd5b5061047d610c34565b60405161045f9190613a5e565b34801561049657600080fd5b506104aa6104a5366004613a8d565b610cc2565b005b3480156104b857600080fd5b506104aa6104c7366004613ab6565b610db5565b3480156104d857600080fd5b506104aa6104e7366004613a8d565b610e2f565b3480156104f857600080fd5b50610501610e8c565b60405190815260200161045f565b34801561051b57600080fd5b50600b5461044b906001600160a01b031681565b34801561053b57600080fd5b50600f5461044b906001600160a01b031681565b34801561055b57600080fd5b5060095461044b906001600160a01b031681565b34801561057b57600080fd5b5060045461044b906001600160a01b031681565b34801561059b57600080fd5b5060025461044b906001600160a01b031681565b3480156105bb57600080fd5b506104aa6105ca366004613ad3565b610eff565b3480156105db57600080fd5b50600e5461044b906001600160a01b031681565b3480156105fb57600080fd5b50610604611137565b60405161045f9190613aec565b34801561061d57600080fd5b506104aa61062c366004613ad3565b6111cc565b34801561063d57600080fd5b506104aa61129a565b34801561065257600080fd5b506104aa6112f3565b34801561066757600080fd5b506104aa61133e565b34801561067c57600080fd5b506104aa611429565b34801561069157600080fd5b5060065461044b906001600160a01b031681565b3480156106b157600080fd5b5061050160105481565b3480156106c757600080fd5b5061050161271081565b3480156106dd57600080fd5b506104aa6114db565b3480156106f257600080fd5b506104aa610701366004613ab6565b611517565b34801561071257600080fd5b50600054600160a01b900460ff165b604051901515815260200161045f565b34801561073d57600080fd5b506000610501565b34801561075157600080fd5b506104aa610760366004613a8d565b611569565b34801561077157600080fd5b50600a5461044b906001600160a01b031681565b34801561079157600080fd5b5060085461044b9061010090046001600160a01b031681565b3480156107b657600080fd5b506104aa6115bf565b3480156107cb57600080fd5b506105016115d1565b3480156107e057600080fd5b506104aa6107ef366004613a8d565b6115ed565b34801561080057600080fd5b5061050160115481565b34801561081657600080fd5b5060165461044b9061010090046001600160a01b031681565b34801561083b57600080fd5b506104aa61167a565b34801561085057600080fd5b5060165461072190600160b01b900460ff1681565b34801561087157600080fd5b506105016116c9565b34801561088657600080fd5b506000546001600160a01b031661044b565b3480156108a457600080fd5b5060055461044b906001600160a01b031681565b3480156108c457600080fd5b506104aa6108d3366004613c27565b6116fa565b3480156108e457600080fd5b506008546107219060ff1681565b3480156108fe57600080fd5b506104aa61090d366004613a8d565b6118a9565b34801561091e57600080fd5b506104aa61092d366004613ad3565b6118ff565b34801561093e57600080fd5b5060035461044b906001600160a01b031681565b34801561095e57600080fd5b506109676119ad565b60405161045f9190613c6c565b34801561098057600080fd5b5060125461072190610100900460ff1681565b34801561099f57600080fd5b5061047d6119e3565b3480156109b457600080fd5b50601554610501565b3480156109c957600080fd5b506105016119f0565b3480156109de57600080fd5b506012546107219060ff1681565b3480156109f857600080fd5b506104aa610a07366004613a8d565b611a21565b348015610a1857600080fd5b50600c5461044b906001600160a01b031681565b348015610a3857600080fd5b506104aa610a47366004613ce9565b611ab7565b348015610a5857600080fd5b506104aa611c24565b348015610a6d57600080fd5b506104aa611d36565b348015610a8257600080fd5b506104aa610a91366004613a8d565b611d75565b348015610aa257600080fd5b50610604611dcb565b348015610ab757600080fd5b5060165461072190600160a81b900460ff1681565b348015610ad857600080fd5b506016546107219060ff1681565b348015610af257600080fd5b50610501603281565b348015610b0757600080fd5b506104aa610b16366004613ab6565b611e00565b348015610b2757600080fd5b50610501611e26565b348015610b3c57600080fd5b50610501611e65565b348015610b5157600080fd5b5061050160175481565b348015610b6757600080fd5b506104aa610b76366004613a8d565b611e84565b348015610b8757600080fd5b50610b9b610b96366004613ad3565b611efa565b60405161045f93929190613d37565b348015610bb657600080fd5b506104aa610bc5366004613ab6565b611fc2565b348015610bd657600080fd5b506104aa612014565b348015610beb57600080fd5b50610604610bfa366004613ad3565b612195565b348015610c0b57600080fd5b5060015461044b906001600160a01b031681565b348015610c2b57600080fd5b506106046121b3565b60148054610c4190613d6b565b80601f0160208091040260200160405190810160405280929190818152602001828054610c6d90613d6b565b8015610cba5780601f10610c8f57610100808354040283529160200191610cba565b820191906000526020600020905b815481529060010190602001808311610c9d57829003601f168201915b505050505081565b60085460ff168015610ce4575060085461010090046001600160a01b03163b15155b15610da957600860019054906101000a90046001600160a01b03166001600160a01b0316633de39c116040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610d3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d629190613da5565b3a1115610da95760405162461bcd60e51b815260206004820152601060248201526f67617320697320746f6f20686967682160801b60448201526064015b60405180910390fd5b610db2816125d6565b50565b6000546001600160a01b0316331480610dd857506003546001600160a01b031633145b610df45760405162461bcd60e51b8152600401610da090613dbe565b6016805460ff60b01b1916600160b01b8315158102919091179182905560ff91041615610e2557610db260006118ff565b610db2600a6118ff565b610e3761279c565b600680546001600160a01b0319166001600160a01b0383169081179091556040519081527f91e28ce4210d103c13c5174847e463b836900f8dc63e9d9b42a4255169d19529906020015b60405180910390a150565b600e546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a08231906024015b602060405180830381865afa158015610ed6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610efa9190613da5565b905090565b6001546001600160a01b03163314610f295760405162461bcd60e51b8152600401610da090613de0565b6009546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015610f72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f969190613da5565b90508181101561107a57600e546001600160a01b0316632e1a7d4d610fbb8385613e16565b6040518263ffffffff1660e01b8152600401610fd991815260200190565b600060405180830381600087803b158015610ff357600080fd5b505af1158015611007573d6000803e3d6000fd5b50506009546040516370a0823160e01b81523060048201526001600160a01b0390911692506370a082319150602401602060405180830381865afa158015611053573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110779190613da5565b90505b818111156110855750805b6000546001600160a01b031632148015906110aa5750600054600160a01b900460ff16155b156110dc576000612710600754836110c29190613e2d565b6110cc9190613e4c565b90506110d88183613e16565b9150505b6001546009546110f9916001600160a01b039182169116836127f6565b7f5b6b431d4476a211bb7d41c20d1aab9ae2321deee0d20be3d9fc9b1093fa6e3d6111226115d1565b60405190815260200160405180910390a15050565b6060610efa6014805461114990613d6b565b80601f016020809104026020016040519081016040528092919081815260200182805461117590613d6b565b80156111c25780601f10611197576101008083540402835291602001916111c2565b820191906000526020600020905b8154815290600101906020018083116111a557829003601f168201915b5050505050612826565b6000546001600160a01b03163314806111ef57506003546001600160a01b031633145b61120b5760405162461bcd60e51b8152600401610da090613dbe565b600654604051631f2afc9960e11b8152600481018390526001600160a01b0390911690633e55f93290602401600060405180830381600087803b15801561125157600080fd5b505af1158015611265573d6000803e3d6000fd5b505050507f9163810ee1e29168d4ce900e48a333fb8fbd3fd070d2bef67f6d4db0846a469f81604051610e8191815260200190565b6000546001600160a01b03163314806112bd57506003546001600160a01b031633145b6112d95760405162461bcd60e51b8152600401610da090613dbe565b6112e1612932565b6112e9612987565b6112f1611c24565b565b6000546001600160a01b031633148061131657506003546001600160a01b031633145b6113325760405162461bcd60e51b8152600401610da090613dbe565b6112f160156000613890565b60085460ff168015611360575060085461010090046001600160a01b03163b15155b1561142057600860019054906101000a90046001600160a01b03166001600160a01b0316633de39c116040518163ffffffff1660e01b81526004016020604051808303816000875af11580156113ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113de9190613da5565b3a11156114205760405162461bcd60e51b815260206004820152601060248201526f67617320697320746f6f20686967682160801b6044820152606401610da0565b6112f1326125d6565b6000546001600160a01b031633148061144c57506003546001600160a01b031633145b6114685760405162461bcd60e51b8152600401610da090613dbe565b61147061167a565b600e546001600160a01b0316632e1a7d4d611489610e8c565b6040518263ffffffff1660e01b81526004016114a791815260200190565b600060405180830381600087803b1580156114c157600080fd5b505af11580156114d5573d6000803e3d6000fd5b50505050565b601654600160b01b900460ff16156112f1576001546001600160a01b031633146114205760405162461bcd60e51b8152600401610da090613de0565b6000546001600160a01b031633148061153a57506003546001600160a01b031633145b6115565760405162461bcd60e51b8152600401610da090613dbe565b6016805460ff1916911515919091179055565b61157161279c565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527fd459c7242e23d490831b5676a611c4342d899d28f342d89ae80793e56a930f3090602001610e81565b6115c761279c565b6112f16000612a09565b60006115db610e8c565b6115e36119f0565b610efa9190613e6e565b6000546001600160a01b031633148061161057506003546001600160a01b031633145b61162c5760405162461bcd60e51b8152600401610da090613dbe565b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527fefb5cfa1a8690c124332ab93324539c5c9c4be03f28aeb8be86f2d8a0c9fb99b90602001610e81565b6000546001600160a01b031633148061169d57506003546001600160a01b031633145b6116b95760405162461bcd60e51b8152600401610da090613dbe565b6116c1612a59565b6112f1612a9c565b600654604051636788231160e11b81523060048201526000916001600160a01b03169063cf10462290602401610eb9565b61170261279c565b600061170d83612826565b905060008160008151811061172457611724613e86565b60209081029190910101516009549091506001600160a01b03908116908216036117785760405162461bcd60e51b8152602060048201526005602482015264085dd85b9d60da1b6044820152606401610da0565b600e546001600160a01b03908116908216036117bf5760405162461bcd60e51b815260206004820152600660248201526521676175676560d01b6044820152606401610da0565b604080516060810182526001600160a01b038381168252602082018781529282018690526015805460018101825560009190915282517f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec475600390920291820180546001600160a01b031916919093161782559251919290917f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec476909101906118669082613eea565b50604091909101516002918201555461188d906001600160a01b0383811691166000612258565b6002546114d5906001600160a01b038381169116600019612258565b6118b161279c565b600580546001600160a01b0319166001600160a01b0383169081179091556040519081527f8041329bf7057543a2c2ff4e4071d1d488a31f82ed44e169b5cd2f04f5e3ac8590602001610e81565b6000546001600160a01b031633148061192257506003546001600160a01b031633145b61193e5760405162461bcd60e51b8152600401610da090613dbe565b60328111156119785760405162461bcd60e51b8152600401610da0906020808252600490820152630216361760e41b604082015260600190565b60078190556040518181527f3aa4413905e8f015896ec5880bdde24088ccb19b578f9fcf6800354d5320d4af90602001610e81565b6119b56138b1565b60405180606001604052806119c8612b1a565b8152602001600081526020016119dc611e65565b9052919050565b60138054610c4190613d6b565b6009546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401610eb9565b6004546001600160a01b03163314611a695760405162461bcd60e51b815260206004820152600b60248201526a085cdd1c985d1959da5cdd60aa1b6044820152606401610da0565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f46d58e3fa07bf19b1d27240f0e286b27e9f7c1b0d88933333fe833b60eec541290602001610e81565b6000546001600160a01b0316331480611ada57506003546001600160a01b031633145b611af65760405162461bcd60e51b8152600401610da090613dbe565b6000611b0182612826565b600a5481519192506001600160a01b0316908290600090611b2457611b24613e86565b60200260200101516001600160a01b031614611b6b5760405162461bcd60e51b8152600401610da09060208082526004908201526310b1b93b60e11b604082015260600190565b600b5481516001600160a01b03909116908290611b8a90600190613e16565b81518110611b9a57611b9a613e86565b60200260200101516001600160a01b031614611be25760405162461bcd60e51b8152602060048201526007602482015266216e617469766560c81b6044820152606401610da0565b611bea612a9c565b6013611bf68382613eea565b5060168054610100600160a81b0319166101006001600160a01b03861602179055611c1f612987565b505050565b611c2c612bc5565b6009546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015611c75573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c999190613da5565b90508015610db257600e5460405163b6b55f2560e01b8152600481018390526001600160a01b039091169063b6b55f2590602401600060405180830381600087803b158015611ce757600080fd5b505af1158015611cfb573d6000803e3d6000fd5b505050507f4d6ce1e535dbade1c23defba91e23b8f791ce5edc0cc320257a2b364e4e38426611d286115d1565b604051908152602001610e81565b6000546001600160a01b0316331480611d5957506003546001600160a01b031633145b6114205760405162461bcd60e51b8152600401610da090613dbe565b611d7d61279c565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f5ca6e64c4522e68e154aa9372f2c5969cd37d9640e59f66953dc472f54ee86fa90602001610e81565b6060610efa6015600081548110611de457611de4613e86565b9060005260206000209060030201600101805461114990613d6b565b611e0861279c565b60168054911515600160a81b0260ff60a81b19909216919091179055565b600e54600a54604051630cff5bdd60e21b81523060048201526001600160a01b03918216602482015260009291909116906333fd6f7490604401610eb9565b60008054600160a01b900460ff16611e7e575060075490565b50600090565b611e8c61279c565b6001600160a01b038116611ef15760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610da0565b610db281612a09565b60158181548110611f0a57600080fd5b6000918252602090912060039091020180546001820180546001600160a01b03909216935090611f3990613d6b565b80601f0160208091040260200160405190810160405280929190818152602001828054611f6590613d6b565b8015611fb25780601f10611f8757610100808354040283529160200191611fb2565b820191906000526020600020905b815481529060010190602001808311611f9557829003601f168201915b5050505050908060020154905083565b6000546001600160a01b0316331480611fe557506003546001600160a01b031633145b6120015760405162461bcd60e51b8152600401610da090613dbe565b6008805460ff1916911515919091179055565b6001546001600160a01b0316331461203e5760405162461bcd60e51b8152600401610da090613de0565b600e546001600160a01b0316632e1a7d4d612057610e8c565b6040518263ffffffff1660e01b815260040161207591815260200190565b600060405180830381600087803b15801561208f57600080fd5b505af11580156120a3573d6000803e3d6000fd5b50506009546040516370a0823160e01b8152306004820152600093506001600160a01b0390911691506370a0823190602401602060405180830381865afa1580156120f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121169190613da5565b60095460015460405163a9059cbb60e01b81526001600160a01b03918216600482015260248101849052929350169063a9059cbb906044016020604051808303816000875af115801561216d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121919190613fb5565b5050565b60606121ad60158381548110611de457611de4613e86565b92915050565b6060610efa6013805461114990613d6b565b60006121d360036014613e6e565b601483516121e19190613e16565b6121ad9190613e4c565b600080806121f984826123a0565b9250612206846014612405565b905061221e61221760036014613e6e565b85906123a0565b91509193909250565b60606121ad61223860036014613e6e565b61224460036014613e6e565b84516122509190613e16565b8491906124b0565b8015806122d25750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa1580156122ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d09190613da5565b155b61233d5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610da0565b6040516001600160a01b038316602482015260448101829052611c1f90849063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612c12565b60006123ad826014613e6e565b835110156123f55760405162461bcd60e51b8152602060048201526015602482015274746f416464726573735f6f75744f66426f756e647360581b6044820152606401610da0565b500160200151600160601b900490565b600081612413816003613e6e565b10156124555760405162461bcd60e51b8152602060048201526011602482015270746f55696e7432345f6f766572666c6f7760781b6044820152606401610da0565b612460826003613e6e565b835110156124a75760405162461bcd60e51b8152602060048201526014602482015273746f55696e7432345f6f75744f66426f756e647360601b6044820152606401610da0565b50016003015190565b6060816124be81601f613e6e565b10156124fd5760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b6044820152606401610da0565b6125078284613e6e565b8451101561254b5760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b6044820152606401610da0565b60608215801561256a57604051915060008252602082016040526125b4565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156125a357805183526020928301920161258b565b5050858452601f01601f1916604052505b5090505b9392505050565b60606125ce8484600085612ce4565b949350505050565b6125de612bc5565b600d546001600160a01b03161561265157600d54600e546040516335313c2160e11b81526001600160a01b039182166004820152911690636a62784290602401600060405180830381600087803b15801561263857600080fd5b505af115801561264c573d6000803e3d6000fd5b505050505b600e54604051634274debf60e11b81523060048201526001600160a01b03909116906384e9bd7e90602401600060405180830381600087803b15801561269657600080fd5b505af11580156126aa573d6000803e3d6000fd5b505050506126b6612e15565b600b546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156126ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127239190613da5565b9050801561219157612734826130dc565b61273c61328b565b60006127466119f0565b9050612750611c24565b42601755337f9bc239f1724cacfb88cb1d66a2dc437467699b68a8c90d7b63110cf4b6f924108261277f6115d1565b6040805192835260208301919091520160405180910390a2505050565b6000546001600160a01b031633146112f15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610da0565b6040516001600160a01b038316602482015260448101829052611c1f90849063a9059cbb60e01b90606401612369565b60606000612833836121c5565b90506000612842826001613e6e565b67ffffffffffffffff81111561285a5761285a613b39565b604051908082528060200260200182016040528015612883578160200160208202803683370190505b50905060005b8281101561292a5760008061289d876121eb565b5091509150818484815181106128b5576128b5613e86565b6001600160a01b039092166020928302919091019091015280846128da856001613e6e565b815181106128ea576128ea613e86565b60200260200101906001600160a01b031690816001600160a01b03168152505061291387612227565b96505050808061292290613fd2565b915050612889565b509392505050565b61293a61374e565b6000805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600e546009546129a6916001600160a01b039182169116600019612258565b600254600b546129c5916001600160a01b039182169116600019612258565b601654600a546129ea916001600160a01b039182169161010090910416600019612258565b600f54600c546112f1916001600160a01b039182169116600019612258565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612a61612bc5565b6000805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861296a3390565b600e54600954612aba916001600160a01b0391821691166000612258565b600254600b54612ad8916001600160a01b0391821691166000612258565b601654600a54612afc916001600160a01b0391821691610100909104166000612258565b600f54600c546112f1916001600160a01b0391821691166000612258565b612b556040518060c0016040528060008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b600654604051639af608c960e01b81523060048201526001600160a01b0390911690639af608c990602401600060405180830381865afa158015612b9d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610efa9190810190613feb565b600054600160a01b900460ff16156112f15760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610da0565b6000612c67826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166125bf9092919063ffffffff16565b805190915015611c1f5780806020019051810190612c859190613fb5565b611c1f5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610da0565b606082471015612d455760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610da0565b6001600160a01b0385163b612d9c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610da0565b600080866001600160a01b03168587604051612db891906140c9565b60006040518083038185875af1925050503d8060008114612df5576040519150601f19603f3d011682016040523d82523d6000602084013e612dfa565b606091505b5091509150612e0a82828661379e565b979650505050505050565b600a546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612e5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e829190613da5565b60165490915060ff168015612e975750600081115b15612f4857612f46601660019054906101000a90046001600160a01b031660138054612ec290613d6b565b80601f0160208091040260200160405190810160405280929190818152602001828054612eee90613d6b565b8015612f3b5780601f10612f1057610100808354040283529160200191612f3b565b820191906000526020600020905b815481529060010190602001808311612f1e57829003601f168201915b5050505050836137d7565b505b60005b60155481101561219157600060158281548110612f6a57612f6a613e86565b60009182526020909120600390910201546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015612fc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fe49190613da5565b905060158281548110612ff957612ff9613e86565b90600052602060002090600302016002015481106130c9576130c76015838154811061302757613027613e86565b9060005260206000209060030201600101805461304390613d6b565b80601f016020809104026020016040519081016040528092919081815260200182805461306f90613d6b565b80156130bc5780601f10613091576101008083540402835291602001916130bc565b820191906000526020600020905b81548152906001019060200180831161309f57829003601f168201915b505050505082613876565b505b50806130d481613fd2565b915050612f4b565b60006130e6612b1a565b8051600b546040516370a0823160e01b8152306004820152929350600092670de0b6b3a764000092916001600160a01b0316906370a0823190602401602060405180830381865afa15801561313f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131639190613da5565b61316d9190613e2d565b6131779190613e4c565b90506000670de0b6b3a76400008360400151836131949190613e2d565b61319e9190613e4c565b600b549091506131b8906001600160a01b031685836127f6565b6000670de0b6b3a76400008460200151846131d39190613e2d565b6131dd9190613e4c565b600554600b549192506131fd916001600160a01b039081169116836127f6565b6000670de0b6b3a76400008560600151856132189190613e2d565b6132229190613e4c565b600454600b54919250613242916001600160a01b039081169116836127f6565b60408051848152602081018490529081018290527fd255b592c7f268a73e534da5219a60ff911b4cf6daae21c7d20527dd657bd99a9060600160405180910390a1505050505050565b600b546040516370a0823160e01b8152306004820152600091829182916001600160a01b0316906370a0823190602401602060405180830381865afa1580156132d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132fc9190613da5565b600b54600c549192506001600160a01b0391821691161461339b576133276014805461304390613d6b565b50600c546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015613370573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133949190613da5565b9250613416565b6016549092508290600160a81b900460ff161561341657600b54604051632e1a7d4d60e01b81526004810183905291925082916001600160a01b0390911690632e1a7d4d90602401600060405180830381600087803b1580156133fd57600080fd5b505af1158015613411573d6000803e3d6000fd5b505050505b6010546002036135275761342861390b565b83816011546002811061343d5761343d613e86565b602002015260125460ff16156134ba57600f5460405163ee22be2360e01b81526001600160a01b039091169063ee22be2390613483908490600090600190600401614108565b600060405180830381600087803b15801561349d57600080fd5b505af11580156134b1573d6000803e3d6000fd5b505050506114d5565b600f54604051630b4c7e4d60e01b81526001600160a01b0390911690630b4c7e4d9085906134ef90859060009060040161412c565b6000604051808303818588803b15801561350857600080fd5b505af115801561351c573d6000803e3d6000fd5b505050505050505050565b60105460030361364857613539613929565b83816011546003811061354e5761354e613e86565b602002015260125460ff161561359457600f546040516315b74c9d60e11b81526001600160a01b0390911690632b6e993a9061348390849060009060019060040161416a565b601254610100900460ff16156135dd57600f5460095460405163a318517960e01b81526001600160a01b039283169263a31851799261348392911690859060009060040161418e565b600f54604051634515cef360e01b81526001600160a01b0390911690634515cef3906136109084906000906004016141b9565b600060405180830381600087803b15801561362a57600080fd5b505af115801561363e573d6000803e3d6000fd5b5050505050505050565b6010546004036136ef5761365a613947565b83816011546004811061366f5761366f613e86565b6020020152601254610100900460ff16156136bd57600f5460095460405163384e03db60e01b81526001600160a01b039283169263384e03db926134839291169085906000906004016141f7565b600f5460405162a6cbcd60e21b81526001600160a01b039091169063029b2f3490613610908490600090600401614222565b601054600503611c1f57613701613965565b83816011546005811061371657613716613e86565b6020020152600f54604051638473849960e01b81526001600160a01b039091169063847384999061361090849060009060040161423d565b600054600160a01b900460ff166112f15760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610da0565b606083156137ad5750816125b8565b8251156137bd5782518084602001fd5b8160405162461bcd60e51b8152600401610da09190613a5e565b6040805160a081018252838152306020820152428183015260608101839052600060808201819052915163c04b8d5960e01b81526001600160a01b0386169063c04b8d599061382a908490600401614275565b6020604051808303816000875af1158015613849573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061386d9190613da5565b95945050505050565b6002546000906125b8906001600160a01b031684846137d7565b5080546000825560030290600052602060002090810190610db29190613983565b60405180606001604052806138f76040518060c0016040528060008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b815260200160008152602001600081525090565b60405180604001604052806002906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b808211156139b85780546001600160a01b031916815560006139a860018301826139bc565b5060006002820155600301613983565b5090565b5080546139c890613d6b565b6000825580601f106139d8575050565b601f016020900490600052602060002090810190610db291905b808211156139b857600081556001016139f2565b60005b83811015613a21578181015183820152602001613a09565b838111156114d55750506000910152565b60008151808452613a4a816020860160208601613a06565b601f01601f19169290920160200192915050565b6020815260006125b86020830184613a32565b80356001600160a01b0381168114613a8857600080fd5b919050565b600060208284031215613a9f57600080fd5b6125b882613a71565b8015158114610db257600080fd5b600060208284031215613ac857600080fd5b81356125b881613aa8565b600060208284031215613ae557600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b81811015613b2d5783516001600160a01b031683529284019291840191600101613b08565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715613b7257613b72613b39565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715613ba157613ba1613b39565b604052919050565b600067ffffffffffffffff821115613bc357613bc3613b39565b50601f01601f191660200190565b600082601f830112613be257600080fd5b8135613bf5613bf082613ba9565b613b78565b818152846020838601011115613c0a57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215613c3a57600080fd5b823567ffffffffffffffff811115613c5157600080fd5b613c5d85828601613bd1565b95602094909401359450505050565b60208152600082516060602084015280516080840152602081015160a0840152604081015160c0840152606081015160e0840152608081015160c0610100850152613cbb610140850182613a32565b905060a082015115156101208501526020850151604085015260408501516060850152809250505092915050565b60008060408385031215613cfc57600080fd5b613d0583613a71565b9150602083013567ffffffffffffffff811115613d2157600080fd5b613d2d85828601613bd1565b9150509250929050565b6001600160a01b0384168152606060208201819052600090613d5b90830185613a32565b9050826040830152949350505050565b600181811c90821680613d7f57607f821691505b602082108103613d9f57634e487b7160e01b600052602260045260246000fd5b50919050565b600060208284031215613db757600080fd5b5051919050565b60208082526008908201526710b6b0b730b3b2b960c11b604082015260600190565b602080825260069082015265085d985d5b1d60d21b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600082821015613e2857613e28613e00565b500390565b6000816000190483118215151615613e4757613e47613e00565b500290565b600082613e6957634e487b7160e01b600052601260045260246000fd5b500490565b60008219821115613e8157613e81613e00565b500190565b634e487b7160e01b600052603260045260246000fd5b601f821115611c1f57600081815260208120601f850160051c81016020861015613ec35750805b601f850160051c820191505b81811015613ee257828155600101613ecf565b505050505050565b815167ffffffffffffffff811115613f0457613f04613b39565b613f1881613f128454613d6b565b84613e9c565b602080601f831160018114613f4d5760008415613f355750858301515b600019600386901b1c1916600185901b178555613ee2565b600085815260208120601f198616915b82811015613f7c57888601518255948401946001909101908401613f5d565b5085821015613f9a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b8051613a8881613aa8565b600060208284031215613fc757600080fd5b81516125b881613aa8565b600060018201613fe457613fe4613e00565b5060010190565b60006020808385031215613ffe57600080fd5b825167ffffffffffffffff8082111561401657600080fd5b9084019060c0828703121561402a57600080fd5b614032613b4f565b825181528383015184820152604083015160408201526060830151606082015260808301518281111561406457600080fd5b83019150601f8201871361407757600080fd5b8151614085613bf082613ba9565b818152888683860101111561409957600080fd5b6140a882878301888701613a06565b6080830152506140ba60a08401613faa565b60a08201529695505050505050565b600082516140db818460208701613a06565b9190910192915050565b8060005b60028110156114d55781518452602093840193909101906001016140e9565b6080810161411682866140e5565b8360408301528215156060830152949350505050565b6060810161413a82856140e5565b8260408301529392505050565b8060005b60038110156114d557815184526020938401939091019060010161414b565b60a081016141788286614147565b8360608301528215156080830152949350505050565b6001600160a01b038416815260a081016141ab6020830185614147565b826080830152949350505050565b608081016141c78285614147565b8260608301529392505050565b8060005b60048110156114d55781518452602093840193909101906001016141d8565b6001600160a01b038416815260c0810161421460208301856141d4565b8260a0830152949350505050565b60a0810161423082856141d4565b8260808301529392505050565b60c08101818460005b6005811015614265578151835260209283019290910190600101614246565b5050508260a08301529392505050565b602081526000825160a0602084015261429160c0840182613a32565b905060018060a01b0360208501511660408401526040840151606084015260608401516080840152608084015160a0840152809150509291505056fea2646970667358221220c6e8711d43030945e7f246f72284c1b4f5b233b65138de79b704169dc817b45c64736f6c634300080f0033000000000000000000000000810d1aaa4cd8f21c23bb648f2dfb9dc232a01f09000000000000000000000000abc000d88f23bb45525e447528dbf656a9d55bf50000000000000000000000002eb49a3eff789d7b2286bf17667acbf12d882c17000000000000000000000000167e42a1c7ab4be03764a2222aac57f5f6754411000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002200000000000000000000000005990002594b13e174885ba4d4ec15b8a8a4485bb000000000000000000000000e592427a0aece92de3edee1f18e0157c058615640000000000000000000000004fed5491693007f0cd49f4614ffc38ab6a04b619000000000000000000000000982f264ce97365864181df65df4931c593a515ad0000000000000000000000003cd5ae887ddf78c58c9c1a063eb343f942dbbce8000000000000000000000000216eee15d1e3faad34181f66dd0b665f556a638d000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002b0994206dfe8de6ec6920ff4d779b0d950605fb53000bb84200000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b42000000000000000000000000000000000000060001f47f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000000000000000000000
Deployed Bytecode
0x60806040526004361061041f5760003560e01c80638cfc02501161021e578063d0e30db011610123578063e941fa78116100ab578063fad4675e1161007a578063fad4675e14610baa578063fb61778714610bca578063fbe7515214610bdf578063fbfa77cf14610bff578063fccf884d14610c1f57600080fd5b8063e941fa7814610b30578063f1a392da14610b45578063f2fde38b14610b5b578063f301af4214610b7b57600080fd5b8063db6b5246116100f2578063db6b524614610aab578063de5b8b2214610acc578063dfbdc43714610ae6578063e4d6cf3014610afb578063e7a7250a14610b1b57600080fd5b8063d0e30db014610a4c578063d801d94614610a61578063d92f3d7314610a76578063da512c3414610a9657600080fd5b8063b20feaaf116101a6578063c1a3d44c11610175578063c1a3d44c146109bd578063c6ddbeeb146109d2578063c7b9d530146109ec578063c89039c514610a0c578063cd80c16714610a2c57600080fd5b8063b20feaaf14610952578063b503ae0014610974578063b7923c6e14610993578063bbb356d5146109a857600080fd5b806397fd323d116101ed57806397fd323d146107315780639f8b5da1146108d8578063a68833e5146108f2578063ac1e502514610912578063aced16611461093257600080fd5b80638cfc0250146108655780638da5cb5b1461087a5780638e145459146108985780638ff4486d146108b857600080fd5b80634700d305116103245780636a4874a1116102ac578063748747e61161027b578063748747e6146107d45780637b898939146107f45780637f1735591461080a5780638456cb591461082f5780638912cb8b1461084457600080fd5b80636a4874a1146107655780636ec232d314610785578063715018a6146107aa578063722713f7146107bf57600080fd5b8063573fef0a116102f3578063573fef0a146106d15780635839b094146106e65780635c975abb1461070657806367a52793146107315780636817031b1461074557600080fd5b80634700d305146106705780634746fb55146106855780634ec18db9146106a557806354518b1a146106bb57600080fd5b80631fe4a686116103a75780633c1deb53116103765780633c1deb53146105ef5780633e55f932146106115780633f4ba83a14610631578063449c27a8146106465780634641257d1461065b57600080fd5b80631fe4a6861461056f578063257ae0de1461058f5780632e1a7d4d146105af5780633930d6b6146105cf57600080fd5b8063106fdbd0116103ee578063106fdbd0146104cc57806311588086146104ec57806311b0b42d1461050f57806316f0115b1461052f5780631f1fcd511461054f57600080fd5b80630d52333c1461042b5780630d6ff380146104685780630e5c011e1461048a5780630e8fbb5a146104ac57600080fd5b3661042657005b600080fd5b34801561043757600080fd5b50600d5461044b906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561047457600080fd5b5061047d610c34565b60405161045f9190613a5e565b34801561049657600080fd5b506104aa6104a5366004613a8d565b610cc2565b005b3480156104b857600080fd5b506104aa6104c7366004613ab6565b610db5565b3480156104d857600080fd5b506104aa6104e7366004613a8d565b610e2f565b3480156104f857600080fd5b50610501610e8c565b60405190815260200161045f565b34801561051b57600080fd5b50600b5461044b906001600160a01b031681565b34801561053b57600080fd5b50600f5461044b906001600160a01b031681565b34801561055b57600080fd5b5060095461044b906001600160a01b031681565b34801561057b57600080fd5b5060045461044b906001600160a01b031681565b34801561059b57600080fd5b5060025461044b906001600160a01b031681565b3480156105bb57600080fd5b506104aa6105ca366004613ad3565b610eff565b3480156105db57600080fd5b50600e5461044b906001600160a01b031681565b3480156105fb57600080fd5b50610604611137565b60405161045f9190613aec565b34801561061d57600080fd5b506104aa61062c366004613ad3565b6111cc565b34801561063d57600080fd5b506104aa61129a565b34801561065257600080fd5b506104aa6112f3565b34801561066757600080fd5b506104aa61133e565b34801561067c57600080fd5b506104aa611429565b34801561069157600080fd5b5060065461044b906001600160a01b031681565b3480156106b157600080fd5b5061050160105481565b3480156106c757600080fd5b5061050161271081565b3480156106dd57600080fd5b506104aa6114db565b3480156106f257600080fd5b506104aa610701366004613ab6565b611517565b34801561071257600080fd5b50600054600160a01b900460ff165b604051901515815260200161045f565b34801561073d57600080fd5b506000610501565b34801561075157600080fd5b506104aa610760366004613a8d565b611569565b34801561077157600080fd5b50600a5461044b906001600160a01b031681565b34801561079157600080fd5b5060085461044b9061010090046001600160a01b031681565b3480156107b657600080fd5b506104aa6115bf565b3480156107cb57600080fd5b506105016115d1565b3480156107e057600080fd5b506104aa6107ef366004613a8d565b6115ed565b34801561080057600080fd5b5061050160115481565b34801561081657600080fd5b5060165461044b9061010090046001600160a01b031681565b34801561083b57600080fd5b506104aa61167a565b34801561085057600080fd5b5060165461072190600160b01b900460ff1681565b34801561087157600080fd5b506105016116c9565b34801561088657600080fd5b506000546001600160a01b031661044b565b3480156108a457600080fd5b5060055461044b906001600160a01b031681565b3480156108c457600080fd5b506104aa6108d3366004613c27565b6116fa565b3480156108e457600080fd5b506008546107219060ff1681565b3480156108fe57600080fd5b506104aa61090d366004613a8d565b6118a9565b34801561091e57600080fd5b506104aa61092d366004613ad3565b6118ff565b34801561093e57600080fd5b5060035461044b906001600160a01b031681565b34801561095e57600080fd5b506109676119ad565b60405161045f9190613c6c565b34801561098057600080fd5b5060125461072190610100900460ff1681565b34801561099f57600080fd5b5061047d6119e3565b3480156109b457600080fd5b50601554610501565b3480156109c957600080fd5b506105016119f0565b3480156109de57600080fd5b506012546107219060ff1681565b3480156109f857600080fd5b506104aa610a07366004613a8d565b611a21565b348015610a1857600080fd5b50600c5461044b906001600160a01b031681565b348015610a3857600080fd5b506104aa610a47366004613ce9565b611ab7565b348015610a5857600080fd5b506104aa611c24565b348015610a6d57600080fd5b506104aa611d36565b348015610a8257600080fd5b506104aa610a91366004613a8d565b611d75565b348015610aa257600080fd5b50610604611dcb565b348015610ab757600080fd5b5060165461072190600160a81b900460ff1681565b348015610ad857600080fd5b506016546107219060ff1681565b348015610af257600080fd5b50610501603281565b348015610b0757600080fd5b506104aa610b16366004613ab6565b611e00565b348015610b2757600080fd5b50610501611e26565b348015610b3c57600080fd5b50610501611e65565b348015610b5157600080fd5b5061050160175481565b348015610b6757600080fd5b506104aa610b76366004613a8d565b611e84565b348015610b8757600080fd5b50610b9b610b96366004613ad3565b611efa565b60405161045f93929190613d37565b348015610bb657600080fd5b506104aa610bc5366004613ab6565b611fc2565b348015610bd657600080fd5b506104aa612014565b348015610beb57600080fd5b50610604610bfa366004613ad3565b612195565b348015610c0b57600080fd5b5060015461044b906001600160a01b031681565b348015610c2b57600080fd5b506106046121b3565b60148054610c4190613d6b565b80601f0160208091040260200160405190810160405280929190818152602001828054610c6d90613d6b565b8015610cba5780601f10610c8f57610100808354040283529160200191610cba565b820191906000526020600020905b815481529060010190602001808311610c9d57829003601f168201915b505050505081565b60085460ff168015610ce4575060085461010090046001600160a01b03163b15155b15610da957600860019054906101000a90046001600160a01b03166001600160a01b0316633de39c116040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610d3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d629190613da5565b3a1115610da95760405162461bcd60e51b815260206004820152601060248201526f67617320697320746f6f20686967682160801b60448201526064015b60405180910390fd5b610db2816125d6565b50565b6000546001600160a01b0316331480610dd857506003546001600160a01b031633145b610df45760405162461bcd60e51b8152600401610da090613dbe565b6016805460ff60b01b1916600160b01b8315158102919091179182905560ff91041615610e2557610db260006118ff565b610db2600a6118ff565b610e3761279c565b600680546001600160a01b0319166001600160a01b0383169081179091556040519081527f91e28ce4210d103c13c5174847e463b836900f8dc63e9d9b42a4255169d19529906020015b60405180910390a150565b600e546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a08231906024015b602060405180830381865afa158015610ed6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610efa9190613da5565b905090565b6001546001600160a01b03163314610f295760405162461bcd60e51b8152600401610da090613de0565b6009546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015610f72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f969190613da5565b90508181101561107a57600e546001600160a01b0316632e1a7d4d610fbb8385613e16565b6040518263ffffffff1660e01b8152600401610fd991815260200190565b600060405180830381600087803b158015610ff357600080fd5b505af1158015611007573d6000803e3d6000fd5b50506009546040516370a0823160e01b81523060048201526001600160a01b0390911692506370a082319150602401602060405180830381865afa158015611053573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110779190613da5565b90505b818111156110855750805b6000546001600160a01b031632148015906110aa5750600054600160a01b900460ff16155b156110dc576000612710600754836110c29190613e2d565b6110cc9190613e4c565b90506110d88183613e16565b9150505b6001546009546110f9916001600160a01b039182169116836127f6565b7f5b6b431d4476a211bb7d41c20d1aab9ae2321deee0d20be3d9fc9b1093fa6e3d6111226115d1565b60405190815260200160405180910390a15050565b6060610efa6014805461114990613d6b565b80601f016020809104026020016040519081016040528092919081815260200182805461117590613d6b565b80156111c25780601f10611197576101008083540402835291602001916111c2565b820191906000526020600020905b8154815290600101906020018083116111a557829003601f168201915b5050505050612826565b6000546001600160a01b03163314806111ef57506003546001600160a01b031633145b61120b5760405162461bcd60e51b8152600401610da090613dbe565b600654604051631f2afc9960e11b8152600481018390526001600160a01b0390911690633e55f93290602401600060405180830381600087803b15801561125157600080fd5b505af1158015611265573d6000803e3d6000fd5b505050507f9163810ee1e29168d4ce900e48a333fb8fbd3fd070d2bef67f6d4db0846a469f81604051610e8191815260200190565b6000546001600160a01b03163314806112bd57506003546001600160a01b031633145b6112d95760405162461bcd60e51b8152600401610da090613dbe565b6112e1612932565b6112e9612987565b6112f1611c24565b565b6000546001600160a01b031633148061131657506003546001600160a01b031633145b6113325760405162461bcd60e51b8152600401610da090613dbe565b6112f160156000613890565b60085460ff168015611360575060085461010090046001600160a01b03163b15155b1561142057600860019054906101000a90046001600160a01b03166001600160a01b0316633de39c116040518163ffffffff1660e01b81526004016020604051808303816000875af11580156113ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113de9190613da5565b3a11156114205760405162461bcd60e51b815260206004820152601060248201526f67617320697320746f6f20686967682160801b6044820152606401610da0565b6112f1326125d6565b6000546001600160a01b031633148061144c57506003546001600160a01b031633145b6114685760405162461bcd60e51b8152600401610da090613dbe565b61147061167a565b600e546001600160a01b0316632e1a7d4d611489610e8c565b6040518263ffffffff1660e01b81526004016114a791815260200190565b600060405180830381600087803b1580156114c157600080fd5b505af11580156114d5573d6000803e3d6000fd5b50505050565b601654600160b01b900460ff16156112f1576001546001600160a01b031633146114205760405162461bcd60e51b8152600401610da090613de0565b6000546001600160a01b031633148061153a57506003546001600160a01b031633145b6115565760405162461bcd60e51b8152600401610da090613dbe565b6016805460ff1916911515919091179055565b61157161279c565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527fd459c7242e23d490831b5676a611c4342d899d28f342d89ae80793e56a930f3090602001610e81565b6115c761279c565b6112f16000612a09565b60006115db610e8c565b6115e36119f0565b610efa9190613e6e565b6000546001600160a01b031633148061161057506003546001600160a01b031633145b61162c5760405162461bcd60e51b8152600401610da090613dbe565b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527fefb5cfa1a8690c124332ab93324539c5c9c4be03f28aeb8be86f2d8a0c9fb99b90602001610e81565b6000546001600160a01b031633148061169d57506003546001600160a01b031633145b6116b95760405162461bcd60e51b8152600401610da090613dbe565b6116c1612a59565b6112f1612a9c565b600654604051636788231160e11b81523060048201526000916001600160a01b03169063cf10462290602401610eb9565b61170261279c565b600061170d83612826565b905060008160008151811061172457611724613e86565b60209081029190910101516009549091506001600160a01b03908116908216036117785760405162461bcd60e51b8152602060048201526005602482015264085dd85b9d60da1b6044820152606401610da0565b600e546001600160a01b03908116908216036117bf5760405162461bcd60e51b815260206004820152600660248201526521676175676560d01b6044820152606401610da0565b604080516060810182526001600160a01b038381168252602082018781529282018690526015805460018101825560009190915282517f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec475600390920291820180546001600160a01b031916919093161782559251919290917f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec476909101906118669082613eea565b50604091909101516002918201555461188d906001600160a01b0383811691166000612258565b6002546114d5906001600160a01b038381169116600019612258565b6118b161279c565b600580546001600160a01b0319166001600160a01b0383169081179091556040519081527f8041329bf7057543a2c2ff4e4071d1d488a31f82ed44e169b5cd2f04f5e3ac8590602001610e81565b6000546001600160a01b031633148061192257506003546001600160a01b031633145b61193e5760405162461bcd60e51b8152600401610da090613dbe565b60328111156119785760405162461bcd60e51b8152600401610da0906020808252600490820152630216361760e41b604082015260600190565b60078190556040518181527f3aa4413905e8f015896ec5880bdde24088ccb19b578f9fcf6800354d5320d4af90602001610e81565b6119b56138b1565b60405180606001604052806119c8612b1a565b8152602001600081526020016119dc611e65565b9052919050565b60138054610c4190613d6b565b6009546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401610eb9565b6004546001600160a01b03163314611a695760405162461bcd60e51b815260206004820152600b60248201526a085cdd1c985d1959da5cdd60aa1b6044820152606401610da0565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f46d58e3fa07bf19b1d27240f0e286b27e9f7c1b0d88933333fe833b60eec541290602001610e81565b6000546001600160a01b0316331480611ada57506003546001600160a01b031633145b611af65760405162461bcd60e51b8152600401610da090613dbe565b6000611b0182612826565b600a5481519192506001600160a01b0316908290600090611b2457611b24613e86565b60200260200101516001600160a01b031614611b6b5760405162461bcd60e51b8152600401610da09060208082526004908201526310b1b93b60e11b604082015260600190565b600b5481516001600160a01b03909116908290611b8a90600190613e16565b81518110611b9a57611b9a613e86565b60200260200101516001600160a01b031614611be25760405162461bcd60e51b8152602060048201526007602482015266216e617469766560c81b6044820152606401610da0565b611bea612a9c565b6013611bf68382613eea565b5060168054610100600160a81b0319166101006001600160a01b03861602179055611c1f612987565b505050565b611c2c612bc5565b6009546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015611c75573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c999190613da5565b90508015610db257600e5460405163b6b55f2560e01b8152600481018390526001600160a01b039091169063b6b55f2590602401600060405180830381600087803b158015611ce757600080fd5b505af1158015611cfb573d6000803e3d6000fd5b505050507f4d6ce1e535dbade1c23defba91e23b8f791ce5edc0cc320257a2b364e4e38426611d286115d1565b604051908152602001610e81565b6000546001600160a01b0316331480611d5957506003546001600160a01b031633145b6114205760405162461bcd60e51b8152600401610da090613dbe565b611d7d61279c565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f5ca6e64c4522e68e154aa9372f2c5969cd37d9640e59f66953dc472f54ee86fa90602001610e81565b6060610efa6015600081548110611de457611de4613e86565b9060005260206000209060030201600101805461114990613d6b565b611e0861279c565b60168054911515600160a81b0260ff60a81b19909216919091179055565b600e54600a54604051630cff5bdd60e21b81523060048201526001600160a01b03918216602482015260009291909116906333fd6f7490604401610eb9565b60008054600160a01b900460ff16611e7e575060075490565b50600090565b611e8c61279c565b6001600160a01b038116611ef15760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610da0565b610db281612a09565b60158181548110611f0a57600080fd5b6000918252602090912060039091020180546001820180546001600160a01b03909216935090611f3990613d6b565b80601f0160208091040260200160405190810160405280929190818152602001828054611f6590613d6b565b8015611fb25780601f10611f8757610100808354040283529160200191611fb2565b820191906000526020600020905b815481529060010190602001808311611f9557829003601f168201915b5050505050908060020154905083565b6000546001600160a01b0316331480611fe557506003546001600160a01b031633145b6120015760405162461bcd60e51b8152600401610da090613dbe565b6008805460ff1916911515919091179055565b6001546001600160a01b0316331461203e5760405162461bcd60e51b8152600401610da090613de0565b600e546001600160a01b0316632e1a7d4d612057610e8c565b6040518263ffffffff1660e01b815260040161207591815260200190565b600060405180830381600087803b15801561208f57600080fd5b505af11580156120a3573d6000803e3d6000fd5b50506009546040516370a0823160e01b8152306004820152600093506001600160a01b0390911691506370a0823190602401602060405180830381865afa1580156120f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121169190613da5565b60095460015460405163a9059cbb60e01b81526001600160a01b03918216600482015260248101849052929350169063a9059cbb906044016020604051808303816000875af115801561216d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121919190613fb5565b5050565b60606121ad60158381548110611de457611de4613e86565b92915050565b6060610efa6013805461114990613d6b565b60006121d360036014613e6e565b601483516121e19190613e16565b6121ad9190613e4c565b600080806121f984826123a0565b9250612206846014612405565b905061221e61221760036014613e6e565b85906123a0565b91509193909250565b60606121ad61223860036014613e6e565b61224460036014613e6e565b84516122509190613e16565b8491906124b0565b8015806122d25750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa1580156122ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d09190613da5565b155b61233d5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610da0565b6040516001600160a01b038316602482015260448101829052611c1f90849063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612c12565b60006123ad826014613e6e565b835110156123f55760405162461bcd60e51b8152602060048201526015602482015274746f416464726573735f6f75744f66426f756e647360581b6044820152606401610da0565b500160200151600160601b900490565b600081612413816003613e6e565b10156124555760405162461bcd60e51b8152602060048201526011602482015270746f55696e7432345f6f766572666c6f7760781b6044820152606401610da0565b612460826003613e6e565b835110156124a75760405162461bcd60e51b8152602060048201526014602482015273746f55696e7432345f6f75744f66426f756e647360601b6044820152606401610da0565b50016003015190565b6060816124be81601f613e6e565b10156124fd5760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b6044820152606401610da0565b6125078284613e6e565b8451101561254b5760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b6044820152606401610da0565b60608215801561256a57604051915060008252602082016040526125b4565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156125a357805183526020928301920161258b565b5050858452601f01601f1916604052505b5090505b9392505050565b60606125ce8484600085612ce4565b949350505050565b6125de612bc5565b600d546001600160a01b03161561265157600d54600e546040516335313c2160e11b81526001600160a01b039182166004820152911690636a62784290602401600060405180830381600087803b15801561263857600080fd5b505af115801561264c573d6000803e3d6000fd5b505050505b600e54604051634274debf60e11b81523060048201526001600160a01b03909116906384e9bd7e90602401600060405180830381600087803b15801561269657600080fd5b505af11580156126aa573d6000803e3d6000fd5b505050506126b6612e15565b600b546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156126ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127239190613da5565b9050801561219157612734826130dc565b61273c61328b565b60006127466119f0565b9050612750611c24565b42601755337f9bc239f1724cacfb88cb1d66a2dc437467699b68a8c90d7b63110cf4b6f924108261277f6115d1565b6040805192835260208301919091520160405180910390a2505050565b6000546001600160a01b031633146112f15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610da0565b6040516001600160a01b038316602482015260448101829052611c1f90849063a9059cbb60e01b90606401612369565b60606000612833836121c5565b90506000612842826001613e6e565b67ffffffffffffffff81111561285a5761285a613b39565b604051908082528060200260200182016040528015612883578160200160208202803683370190505b50905060005b8281101561292a5760008061289d876121eb565b5091509150818484815181106128b5576128b5613e86565b6001600160a01b039092166020928302919091019091015280846128da856001613e6e565b815181106128ea576128ea613e86565b60200260200101906001600160a01b031690816001600160a01b03168152505061291387612227565b96505050808061292290613fd2565b915050612889565b509392505050565b61293a61374e565b6000805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600e546009546129a6916001600160a01b039182169116600019612258565b600254600b546129c5916001600160a01b039182169116600019612258565b601654600a546129ea916001600160a01b039182169161010090910416600019612258565b600f54600c546112f1916001600160a01b039182169116600019612258565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b612a61612bc5565b6000805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861296a3390565b600e54600954612aba916001600160a01b0391821691166000612258565b600254600b54612ad8916001600160a01b0391821691166000612258565b601654600a54612afc916001600160a01b0391821691610100909104166000612258565b600f54600c546112f1916001600160a01b0391821691166000612258565b612b556040518060c0016040528060008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b600654604051639af608c960e01b81523060048201526001600160a01b0390911690639af608c990602401600060405180830381865afa158015612b9d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610efa9190810190613feb565b600054600160a01b900460ff16156112f15760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610da0565b6000612c67826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166125bf9092919063ffffffff16565b805190915015611c1f5780806020019051810190612c859190613fb5565b611c1f5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610da0565b606082471015612d455760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610da0565b6001600160a01b0385163b612d9c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610da0565b600080866001600160a01b03168587604051612db891906140c9565b60006040518083038185875af1925050503d8060008114612df5576040519150601f19603f3d011682016040523d82523d6000602084013e612dfa565b606091505b5091509150612e0a82828661379e565b979650505050505050565b600a546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612e5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e829190613da5565b60165490915060ff168015612e975750600081115b15612f4857612f46601660019054906101000a90046001600160a01b031660138054612ec290613d6b565b80601f0160208091040260200160405190810160405280929190818152602001828054612eee90613d6b565b8015612f3b5780601f10612f1057610100808354040283529160200191612f3b565b820191906000526020600020905b815481529060010190602001808311612f1e57829003601f168201915b5050505050836137d7565b505b60005b60155481101561219157600060158281548110612f6a57612f6a613e86565b60009182526020909120600390910201546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015612fc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fe49190613da5565b905060158281548110612ff957612ff9613e86565b90600052602060002090600302016002015481106130c9576130c76015838154811061302757613027613e86565b9060005260206000209060030201600101805461304390613d6b565b80601f016020809104026020016040519081016040528092919081815260200182805461306f90613d6b565b80156130bc5780601f10613091576101008083540402835291602001916130bc565b820191906000526020600020905b81548152906001019060200180831161309f57829003601f168201915b505050505082613876565b505b50806130d481613fd2565b915050612f4b565b60006130e6612b1a565b8051600b546040516370a0823160e01b8152306004820152929350600092670de0b6b3a764000092916001600160a01b0316906370a0823190602401602060405180830381865afa15801561313f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131639190613da5565b61316d9190613e2d565b6131779190613e4c565b90506000670de0b6b3a76400008360400151836131949190613e2d565b61319e9190613e4c565b600b549091506131b8906001600160a01b031685836127f6565b6000670de0b6b3a76400008460200151846131d39190613e2d565b6131dd9190613e4c565b600554600b549192506131fd916001600160a01b039081169116836127f6565b6000670de0b6b3a76400008560600151856132189190613e2d565b6132229190613e4c565b600454600b54919250613242916001600160a01b039081169116836127f6565b60408051848152602081018490529081018290527fd255b592c7f268a73e534da5219a60ff911b4cf6daae21c7d20527dd657bd99a9060600160405180910390a1505050505050565b600b546040516370a0823160e01b8152306004820152600091829182916001600160a01b0316906370a0823190602401602060405180830381865afa1580156132d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132fc9190613da5565b600b54600c549192506001600160a01b0391821691161461339b576133276014805461304390613d6b565b50600c546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015613370573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133949190613da5565b9250613416565b6016549092508290600160a81b900460ff161561341657600b54604051632e1a7d4d60e01b81526004810183905291925082916001600160a01b0390911690632e1a7d4d90602401600060405180830381600087803b1580156133fd57600080fd5b505af1158015613411573d6000803e3d6000fd5b505050505b6010546002036135275761342861390b565b83816011546002811061343d5761343d613e86565b602002015260125460ff16156134ba57600f5460405163ee22be2360e01b81526001600160a01b039091169063ee22be2390613483908490600090600190600401614108565b600060405180830381600087803b15801561349d57600080fd5b505af11580156134b1573d6000803e3d6000fd5b505050506114d5565b600f54604051630b4c7e4d60e01b81526001600160a01b0390911690630b4c7e4d9085906134ef90859060009060040161412c565b6000604051808303818588803b15801561350857600080fd5b505af115801561351c573d6000803e3d6000fd5b505050505050505050565b60105460030361364857613539613929565b83816011546003811061354e5761354e613e86565b602002015260125460ff161561359457600f546040516315b74c9d60e11b81526001600160a01b0390911690632b6e993a9061348390849060009060019060040161416a565b601254610100900460ff16156135dd57600f5460095460405163a318517960e01b81526001600160a01b039283169263a31851799261348392911690859060009060040161418e565b600f54604051634515cef360e01b81526001600160a01b0390911690634515cef3906136109084906000906004016141b9565b600060405180830381600087803b15801561362a57600080fd5b505af115801561363e573d6000803e3d6000fd5b5050505050505050565b6010546004036136ef5761365a613947565b83816011546004811061366f5761366f613e86565b6020020152601254610100900460ff16156136bd57600f5460095460405163384e03db60e01b81526001600160a01b039283169263384e03db926134839291169085906000906004016141f7565b600f5460405162a6cbcd60e21b81526001600160a01b039091169063029b2f3490613610908490600090600401614222565b601054600503611c1f57613701613965565b83816011546005811061371657613716613e86565b6020020152600f54604051638473849960e01b81526001600160a01b039091169063847384999061361090849060009060040161423d565b600054600160a01b900460ff166112f15760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610da0565b606083156137ad5750816125b8565b8251156137bd5782518084602001fd5b8160405162461bcd60e51b8152600401610da09190613a5e565b6040805160a081018252838152306020820152428183015260608101839052600060808201819052915163c04b8d5960e01b81526001600160a01b0386169063c04b8d599061382a908490600401614275565b6020604051808303816000875af1158015613849573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061386d9190613da5565b95945050505050565b6002546000906125b8906001600160a01b031684846137d7565b5080546000825560030290600052602060002090810190610db29190613983565b60405180606001604052806138f76040518060c0016040528060008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b815260200160008152602001600081525090565b60405180604001604052806002906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b808211156139b85780546001600160a01b031916815560006139a860018301826139bc565b5060006002820155600301613983565b5090565b5080546139c890613d6b565b6000825580601f106139d8575050565b601f016020900490600052602060002090810190610db291905b808211156139b857600081556001016139f2565b60005b83811015613a21578181015183820152602001613a09565b838111156114d55750506000910152565b60008151808452613a4a816020860160208601613a06565b601f01601f19169290920160200192915050565b6020815260006125b86020830184613a32565b80356001600160a01b0381168114613a8857600080fd5b919050565b600060208284031215613a9f57600080fd5b6125b882613a71565b8015158114610db257600080fd5b600060208284031215613ac857600080fd5b81356125b881613aa8565b600060208284031215613ae557600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b81811015613b2d5783516001600160a01b031683529284019291840191600101613b08565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715613b7257613b72613b39565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715613ba157613ba1613b39565b604052919050565b600067ffffffffffffffff821115613bc357613bc3613b39565b50601f01601f191660200190565b600082601f830112613be257600080fd5b8135613bf5613bf082613ba9565b613b78565b818152846020838601011115613c0a57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215613c3a57600080fd5b823567ffffffffffffffff811115613c5157600080fd5b613c5d85828601613bd1565b95602094909401359450505050565b60208152600082516060602084015280516080840152602081015160a0840152604081015160c0840152606081015160e0840152608081015160c0610100850152613cbb610140850182613a32565b905060a082015115156101208501526020850151604085015260408501516060850152809250505092915050565b60008060408385031215613cfc57600080fd5b613d0583613a71565b9150602083013567ffffffffffffffff811115613d2157600080fd5b613d2d85828601613bd1565b9150509250929050565b6001600160a01b0384168152606060208201819052600090613d5b90830185613a32565b9050826040830152949350505050565b600181811c90821680613d7f57607f821691505b602082108103613d9f57634e487b7160e01b600052602260045260246000fd5b50919050565b600060208284031215613db757600080fd5b5051919050565b60208082526008908201526710b6b0b730b3b2b960c11b604082015260600190565b602080825260069082015265085d985d5b1d60d21b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600082821015613e2857613e28613e00565b500390565b6000816000190483118215151615613e4757613e47613e00565b500290565b600082613e6957634e487b7160e01b600052601260045260246000fd5b500490565b60008219821115613e8157613e81613e00565b500190565b634e487b7160e01b600052603260045260246000fd5b601f821115611c1f57600081815260208120601f850160051c81016020861015613ec35750805b601f850160051c820191505b81811015613ee257828155600101613ecf565b505050505050565b815167ffffffffffffffff811115613f0457613f04613b39565b613f1881613f128454613d6b565b84613e9c565b602080601f831160018114613f4d5760008415613f355750858301515b600019600386901b1c1916600185901b178555613ee2565b600085815260208120601f198616915b82811015613f7c57888601518255948401946001909101908401613f5d565b5085821015613f9a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b8051613a8881613aa8565b600060208284031215613fc757600080fd5b81516125b881613aa8565b600060018201613fe457613fe4613e00565b5060010190565b60006020808385031215613ffe57600080fd5b825167ffffffffffffffff8082111561401657600080fd5b9084019060c0828703121561402a57600080fd5b614032613b4f565b825181528383015184820152604083015160408201526060830151606082015260808301518281111561406457600080fd5b83019150601f8201871361407757600080fd5b8151614085613bf082613ba9565b818152888683860101111561409957600080fd5b6140a882878301888701613a06565b6080830152506140ba60a08401613faa565b60a08201529695505050505050565b600082516140db818460208701613a06565b9190910192915050565b8060005b60028110156114d55781518452602093840193909101906001016140e9565b6080810161411682866140e5565b8360408301528215156060830152949350505050565b6060810161413a82856140e5565b8260408301529392505050565b8060005b60038110156114d557815184526020938401939091019060010161414b565b60a081016141788286614147565b8360608301528215156080830152949350505050565b6001600160a01b038416815260a081016141ab6020830185614147565b826080830152949350505050565b608081016141c78285614147565b8260608301529392505050565b8060005b60048110156114d55781518452602093840193909101906001016141d8565b6001600160a01b038416815260c0810161421460208301856141d4565b8260a0830152949350505050565b60a0810161423082856141d4565b8260808301529392505050565b60c08101818460005b6005811015614265578151835260209283019290910190600101614246565b5050508260a08301529392505050565b602081526000825160a0602084015261429160c0840182613a32565b905060018060a01b0360208501511660408401526040840151606084015260608401516080840152608084015160a0840152809150509291505056fea2646970667358221220c6e8711d43030945e7f246f72284c1b4f5b233b65138de79b704169dc817b45c64736f6c634300080f0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000810d1aaa4cd8f21c23bb648f2dfb9dc232a01f09000000000000000000000000abc000d88f23bb45525e447528dbf656a9d55bf50000000000000000000000002eb49a3eff789d7b2286bf17667acbf12d882c17000000000000000000000000167e42a1c7ab4be03764a2222aac57f5f6754411000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002200000000000000000000000005990002594b13e174885ba4d4ec15b8a8a4485bb000000000000000000000000e592427a0aece92de3edee1f18e0157c058615640000000000000000000000004fed5491693007f0cd49f4614ffc38ab6a04b619000000000000000000000000982f264ce97365864181df65df4931c593a515ad0000000000000000000000003cd5ae887ddf78c58c9c1a063eb343f942dbbce8000000000000000000000000216eee15d1e3faad34181f66dd0b665f556a638d000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002b0994206dfe8de6ec6920ff4d779b0d950605fb53000bb84200000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b42000000000000000000000000000000000000060001f47f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _want (address): 0x810D1AaA4Cd8F21c23bB648F2dfb9DC232A01F09
Arg [1] : _gaugeFactory (address): 0xabC000d88f23Bb45525E447528DBF656A9D55bf5
Arg [2] : _gauge (address): 0x2EB49A3eff789d7B2286Bf17667acbF12d882c17
Arg [3] : _pool (address): 0x167e42a1C7ab4Be03764A2222aAC57F5f6754411
Arg [4] : _params (uint256[]): 4,2,0,1
Arg [5] : _paths (bytes[]): System.Byte[],System.Byte[]
Arg [6] : _commonAddresses (tuple):
Arg [1] : vault (address): 0x5990002594b13e174885ba4D4Ec15B8a8A4485bb
Arg [2] : unirouter (address): 0xE592427A0AEce92De3Edee1F18E0157C05861564
Arg [3] : keeper (address): 0x4fED5491693007f0CD49f4614FFC38Ab6A04B619
Arg [4] : strategist (address): 0x982F264ce97365864181df65dF4931C593A515ad
Arg [5] : beefyFeeRecipient (address): 0x3Cd5Ae887Ddf78c58c9C1a063EB343F942DbbcE8
Arg [6] : beefyFeeConfig (address): 0x216EEE15D1e3fAAD34181f66dd0B665f556a638d
-----Encoded View---------------
26 Constructor Arguments found :
Arg [0] : 000000000000000000000000810d1aaa4cd8f21c23bb648f2dfb9dc232a01f09
Arg [1] : 000000000000000000000000abc000d88f23bb45525e447528dbf656a9d55bf5
Arg [2] : 0000000000000000000000002eb49a3eff789d7b2286bf17667acbf12d882c17
Arg [3] : 000000000000000000000000167e42a1c7ab4be03764a2222aac57f5f6754411
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000180
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000220
Arg [6] : 0000000000000000000000005990002594b13e174885ba4d4ec15b8a8a4485bb
Arg [7] : 000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564
Arg [8] : 0000000000000000000000004fed5491693007f0cd49f4614ffc38ab6a04b619
Arg [9] : 000000000000000000000000982f264ce97365864181df65df4931c593a515ad
Arg [10] : 0000000000000000000000003cd5ae887ddf78c58c9c1a063eb343f942dbbce8
Arg [11] : 000000000000000000000000216eee15d1e3faad34181f66dd0b665f556a638d
Arg [12] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [14] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [15] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [16] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [17] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [18] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [19] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [20] : 000000000000000000000000000000000000000000000000000000000000002b
Arg [21] : 0994206dfe8de6ec6920ff4d779b0d950605fb53000bb8420000000000000000
Arg [22] : 0000000000000000000006000000000000000000000000000000000000000000
Arg [23] : 000000000000000000000000000000000000000000000000000000000000002b
Arg [24] : 42000000000000000000000000000000000000060001f47f5c764cbc14f9669b
Arg [25] : 88837ca1490cca17c31607000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
78509:13356:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78832:27;;;;;;;;;;-1:-1:-1;78832:27:0;;;;-1:-1:-1;;;;;78832:27:0;;;;;;-1:-1:-1;;;;;178:32:1;;;160:51;;148:2;133:18;78832:27:0;;;;;;;;79109:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;82444:117::-;;;;;;;;;;-1:-1:-1;82444:117:0;;;;;:::i;:::-;;:::i;:::-;;89596:260;;;;;;;;;;-1:-1:-1;89596:260:0;;;;;:::i;:::-;;:::i;47792:184::-;;;;;;;;;;-1:-1:-1;47792:184:0;;;;;:::i;:::-;;:::i;87673:133::-;;;;;;;;;;;;;:::i;:::-;;;1853:25:1;;;1841:2;1826:18;87673:133:0;1707:177:1;78738:21:0;;;;;;;;;;-1:-1:-1;78738:21:0;;;;-1:-1:-1;;;;;78738:21:0;;;78900:19;;;;;;;;;;-1:-1:-1;78900:19:0;;;;-1:-1:-1;;;;;78900:19:0;;;78670;;;;;;;;;;-1:-1:-1;78670:19:0;;;;-1:-1:-1;;;;;78670:19:0;;;44496:25;;;;;;;;;;-1:-1:-1;44496:25:0;;;;-1:-1:-1;;;;;44496:25:0;;;44437:24;;;;;;;;;;-1:-1:-1;44437:24:0;;;;-1:-1:-1;;;;;44437:24:0;;;81430:722;;;;;;;;;;-1:-1:-1;81430:722:0;;;;;:::i;:::-;;:::i;78866:27::-;;;;;;;;;;-1:-1:-1;78866:27:0;;;;-1:-1:-1;;;;;78866:27:0;;;88405:127;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;46313:152::-;;;;;;;;;;-1:-1:-1;46313:152:0;;;;;:::i;:::-;;:::i;91139:121::-;;;;;;;;;;;;;:::i;87137:83::-;;;;;;;;;;;;;:::i;82350:86::-;;;;;;;;;;;;;:::i;90902:126::-;;;;;;;;;;;;;:::i;44567:32::-;;;;;;;;;;-1:-1:-1;44567:32:0;;;;-1:-1:-1;;;;;44567:32:0;;;78926:20;;;;;;;;;;;;;;;;44703:46;;;;;;;;;;;;44744:5;44703:46;;82160:182;;;;;;;;;;;;;:::i;88924:99::-;;;;;;;;;;-1:-1:-1;88924:99:0;;;;;:::i;:::-;;:::i;42394:86::-;;;;;;;;;;-1:-1:-1;42441:4:0;42465:7;-1:-1:-1;;;42465:7:0;;;;42394:86;;;3129:14:1;;3122:22;3104:41;;3092:2;3077:18;42394:86:0;2964:187:1;47984:87:0;;;;;;;;;;-1:-1:-1;48035:7:0;47984:87;;46752:118;;;;;;;;;;-1:-1:-1;46752:118:0;;;;;:::i;:::-;;:::i;78713:18::-;;;;;;;;;;-1:-1:-1;78713:18:0;;;;-1:-1:-1;;;;;78713:18:0;;;48581:77;;;;;;;;;;-1:-1:-1;48581:77:0;;;;;;;-1:-1:-1;;;;;48581:77:0;;;39906:103;;;;;;;;;;;;;:::i;87294:110::-;;;;;;;;;;;;;:::i;47093:126::-;;;;;;;;;;-1:-1:-1;47093:126:0;;;;;:::i;:::-;;:::i;78953:24::-;;;;;;;;;;;;;;;;79435;;;;;;;;;;-1:-1:-1;79435:24:0;;;;;;;-1:-1:-1;;;;;79435:24:0;;;91036:95;;;;;;;;;;;;;:::i;79561:28::-;;;;;;;;;;-1:-1:-1;79561:28:0;;;;-1:-1:-1;;;79561:28:0;;;;;;46182:123;;;;;;;;;;;;;:::i;39258:87::-;;;;;;;;;;-1:-1:-1;39304:7:0;39331:6;-1:-1:-1;;;;;39331:6:0;39258:87;;44528:32;;;;;;;;;;-1:-1:-1;44528:32:0;;;;-1:-1:-1;;;;;44528:32:0;;;86614:515;;;;;;;;;;-1:-1:-1;86614:515:0;;;;;:::i;:::-;;:::i;48536:36::-;;;;;;;;;;-1:-1:-1;48536:36:0;;;;;;;;47545:190;;;;;;;;;;-1:-1:-1;47545:190:0;;;;;:::i;:::-;;:::i;46503:::-;;;;;;;;;;-1:-1:-1;46503:190:0;;;;;:::i;:::-;;:::i;44468:21::-;;;;;;;;;;-1:-1:-1;44468:21:0;;;;-1:-1:-1;;;;;44468:21:0;;;46018:156;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;79016:23::-;;;;;;;;;;-1:-1:-1;79016:23:0;;;;;;;;;;;79074:28;;;;;;;;;;;;;:::i;88822:94::-;;;;;;;;;;-1:-1:-1;88894:7:0;:14;88822:94;;87471:118;;;;;;;;;;;;;:::i;78984:25::-;;;;;;;;;;-1:-1:-1;78984:25:0;;;;;;;;47284:197;;;;;;;;;;-1:-1:-1;47284:197:0;;;;;:::i;:::-;;:::i;78766:27::-;;;;;;;;;;-1:-1:-1;78766:27:0;;;;-1:-1:-1;;;;;78766:27:0;;;89031:434;;;;;;;;;;-1:-1:-1;89031:434:0;;;;;:::i;:::-;;:::i;81168:254::-;;;;;;;;;;;;;:::i;82569:85::-;;;;;;;;;;;;;:::i;46904:142::-;;;;;;;;;;-1:-1:-1;46904:142:0;;;;;:::i;:::-;;:::i;88540:130::-;;;;;;;;;;;;;:::i;79527:25::-;;;;;;;;;;-1:-1:-1;79527:25:0;;;;-1:-1:-1;;;79527:25:0;;;;;;79399:29;;;;;;;;;;-1:-1:-1;79399:29:0;;;;;;;;44649:47;;;;;;;;;;;;44694:2;44649:47;;89473:115;;;;;;;;;;-1:-1:-1;89473:115:0;;;;;:::i;:::-;;:::i;89900:148::-;;;;;;;;;;;;;:::i;48079:115::-;;;;;;;;;;;;;:::i;79596:26::-;;;;;;;;;;;;;;;;40164:201;;;;;;;;;;-1:-1:-1;40164:201:0;;;;;:::i;:::-;;:::i;79300:23::-;;;;;;;;;;-1:-1:-1;79300:23:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;90316:133::-;;;;;;;;;;-1:-1:-1;90316:133:0;;;;;:::i;:::-;;:::i;90549:271::-;;;;;;;;;;;;;:::i;88678:136::-;;;;;;;;;;-1:-1:-1;88678:136:0;;;;;:::i;:::-;;:::i;44410:20::-;;;;;;;;;;-1:-1:-1;44410:20:0;;;;-1:-1:-1;;;;;44410:20:0;;;88278:119;;;;;;;;;;;;;:::i;79109:32::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;82444:117::-;48705:17;;;;:49;;;;-1:-1:-1;48745:8:0;;;;;-1:-1:-1;;;;;48745:8:0;21361:19;:23;;48726:28;48701:159;;;48804:8;;;;;;;;;-1:-1:-1;;;;;48804:8:0;-1:-1:-1;;;;;48794:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48779:11;:48;;48771:77;;;;-1:-1:-1;;;48771:77:0;;7386:2:1;48771:77:0;;;7368:21:1;7425:2;7405:18;;;7398:30;-1:-1:-1;;;7444:18:1;;;7437:46;7500:18;;48771:77:0;;;;;;;;;82527:26:::1;82536:16;82527:8;:26::i;:::-;82444:117:::0;:::o;89596:260::-;39304:7;39331:6;-1:-1:-1;;;;;39331:6:0;45674:10;:21;;:45;;-1:-1:-1;45713:6:0;;-1:-1:-1;;;;;45713:6:0;45699:10;:20;45674:45;45666:66;;;;-1:-1:-1;;;45666:66:0;;;;;;;:::i;:::-;89681:16:::1;:36:::0;;-1:-1:-1;;;;89681:36:0::1;-1:-1:-1::0;;;89681:36:0;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;;::::1;89732:16:::0;::::1;;89728:121;;;89765:19;89782:1;89765:16;:19::i;89728:121::-;89817:20;89834:2;89817:16;:20::i;47792:184::-:0;39144:13;:11;:13::i;:::-;47874:14:::1;:44:::0;;-1:-1:-1;;;;;;47874:44:0::1;-1:-1:-1::0;;;;;47874:44:0;::::1;::::0;;::::1;::::0;;;47934:34:::1;::::0;160:51:1;;;47934:34:0::1;::::0;148:2:1;133:18;47934:34:0::1;;;;;;;;47792:184:::0;:::o;87673:133::-;87760:12;;87746:52;;-1:-1:-1;;;87746:52:0;;87792:4;87746:52;;;160:51:1;87719:7:0;;-1:-1:-1;;;;;87760:12:0;;87746:37;;133:18:1;;87746:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;87739:59;;87673:133;:::o;81430:722::-;81507:5;;-1:-1:-1;;;;;81507:5:0;81493:10;:19;81485:38;;;;-1:-1:-1;;;81485:38:0;;;;;;;:::i;:::-;81561:4;;81554:37;;-1:-1:-1;;;81554:37:0;;81585:4;81554:37;;;160:51:1;81536:15:0;;-1:-1:-1;;;;;81561:4:0;;81554:22;;133:18:1;;81554:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;81536:55;;81618:7;81608;:17;81604:167;;;81656:12;;-1:-1:-1;;;;;81656:12:0;81642:36;81679:17;81689:7;81679;:17;:::i;:::-;81642:55;;;;;;;;;;;;;1853:25:1;;1841:2;1826:18;;1707:177;81642:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;81729:4:0;;81722:37;;-1:-1:-1;;;81722:37:0;;81753:4;81722:37;;;160:51:1;-1:-1:-1;;;;;81729:4:0;;;;-1:-1:-1;81722:22:0;;-1:-1:-1;133:18:1;;81722:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;81712:47;;81604:167;81797:7;81787;:17;81783:67;;;-1:-1:-1;81831:7:0;81783:67;39304:7;39331:6;-1:-1:-1;;;;;39331:6:0;81866:9;:20;;;;:33;;-1:-1:-1;42441:4:0;42465:7;-1:-1:-1;;;42465:7:0;;;;81890:9;81866:33;81862:190;;;81916:27;44744:5;81956:13;;81946:7;:23;;;;:::i;:::-;:40;;;;:::i;:::-;81916:70;-1:-1:-1;82011:29:0;81916:70;82011:7;:29;:::i;:::-;82001:39;;81901:151;81862:190;82090:5;;82071:4;;82064:41;;-1:-1:-1;;;;;82071:4:0;;;;82090:5;82097:7;82064:25;:41::i;:::-;82123:21;82132:11;:9;:11::i;:::-;82123:21;;1853:25:1;;;1841:2;1826:18;82123:21:0;;;;;;;81474:678;81430:722;:::o;88405:127::-;88455:16;88491:33;88504:19;88491:33;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:12;:33::i;46313:152::-;39304:7;39331:6;-1:-1:-1;;;;;39331:6:0;45674:10;:21;;:45;;-1:-1:-1;45713:6:0;;-1:-1:-1;;;;;45713:6:0;45699:10;:20;45674:45;45666:66;;;;-1:-1:-1;;;45666:66:0;;;;;;;:::i;:::-;46384:14:::1;::::0;:36:::1;::::0;-1:-1:-1;;;46384:36:0;;::::1;::::0;::::1;1853:25:1::0;;;-1:-1:-1;;;;;46384:14:0;;::::1;::::0;:28:::1;::::0;1826:18:1;;46384:36:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;46436:21;46450:6;46436:21;;;;1853:25:1::0;;1841:2;1826:18;;1707:177;91139:121:0;39304:7;39331:6;-1:-1:-1;;;;;39331:6:0;45674:10;:21;;:45;;-1:-1:-1;45713:6:0;;-1:-1:-1;;;;;45713:6:0;45699:10;:20;45674:45;45666:66;;;;-1:-1:-1;;;45666:66:0;;;;;;;:::i;:::-;91190:10:::1;:8;:10::i;:::-;91213:17;:15;:17::i;:::-;91243:9;:7;:9::i;:::-;91139:121::o:0;87137:83::-;39304:7;39331:6;-1:-1:-1;;;;;39331:6:0;45674:10;:21;;:45;;-1:-1:-1;45713:6:0;;-1:-1:-1;;;;;45713:6:0;45699:10;:20;45674:45;45666:66;;;;-1:-1:-1;;;45666:66:0;;;;;;;:::i;:::-;87198:14:::1;87205:7;;87198:14;:::i;82350:86::-:0;48705:17;;;;:49;;;;-1:-1:-1;48745:8:0;;;;;-1:-1:-1;;;;;48745:8:0;21361:19;:23;;48726:28;48701:159;;;48804:8;;;;;;;;;-1:-1:-1;;;;;48804:8:0;-1:-1:-1;;;;;48794:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48779:11;:48;;48771:77;;;;-1:-1:-1;;;48771:77:0;;7386:2:1;48771:77:0;;;7368:21:1;7425:2;7405:18;;;7398:30;-1:-1:-1;;;7444:18:1;;;7437:46;7500:18;;48771:77:0;7184:340:1;48771:77:0;82409:19:::1;82418:9;82409:8;:19::i;90902:126::-:0;39304:7;39331:6;-1:-1:-1;;;;;39331:6:0;45674:10;:21;;:45;;-1:-1:-1;45713:6:0;;-1:-1:-1;;;;;45713:6:0;45699:10;:20;45674:45;45666:66;;;;-1:-1:-1;;;45666:66:0;;;;;;;:::i;:::-;90949:7:::1;:5;:7::i;:::-;90981:12;::::0;-1:-1:-1;;;;;90981:12:0::1;90967:36;91004:15;:13;:15::i;:::-;90967:53;;;;;;;;;;;;;1853:25:1::0;;1841:2;1826:18;;1707:177;90967:53:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;90902:126::o:0;82160:182::-;82218:16;;-1:-1:-1;;;82218:16:0;;;;82214:121;;;82273:5;;-1:-1:-1;;;;;82273:5:0;82259:10;:19;82251:38;;;;-1:-1:-1;;;82251:38:0;;;;;;;:::i;88924:99::-;39304:7;39331:6;-1:-1:-1;;;;;39331:6:0;45674:10;:21;;:45;;-1:-1:-1;45713:6:0;;-1:-1:-1;;;;;45713:6:0;45699:10;:20;45674:45;45666:66;;;;-1:-1:-1;;;45666:66:0;;;;;;;:::i;:::-;88994:10:::1;:21:::0;;-1:-1:-1;;88994:21:0::1;::::0;::::1;;::::0;;;::::1;::::0;;88924:99::o;46752:118::-;39144:13;:11;:13::i;:::-;46816:5:::1;:14:::0;;-1:-1:-1;;;;;;46816:14:0::1;-1:-1:-1::0;;;;;46816:14:0;::::1;::::0;;::::1;::::0;;;46846:16:::1;::::0;160:51:1;;;46846:16:0::1;::::0;148:2:1;133:18;46846:16:0::1;14:203:1::0;39906:103:0;39144:13;:11;:13::i;:::-;39971:30:::1;39998:1;39971:18;:30::i;87294:110::-:0;87336:7;87381:15;:13;:15::i;:::-;87363;:13;:15::i;:::-;:33;;;;:::i;47093:126::-;39304:7;39331:6;-1:-1:-1;;;;;39331:6:0;45674:10;:21;;:45;;-1:-1:-1;45713:6:0;;-1:-1:-1;;;;;45713:6:0;45699:10;:20;45674:45;45666:66;;;;-1:-1:-1;;;45666:66:0;;;;;;;:::i;:::-;47161:6:::1;:16:::0;;-1:-1:-1;;;;;;47161:16:0::1;-1:-1:-1::0;;;;;47161:16:0;::::1;::::0;;::::1;::::0;;;47193:18:::1;::::0;160:51:1;;;47193:18:0::1;::::0;148:2:1;133:18;47193::0::1;14:203:1::0;91036:95:0;39304:7;39331:6;-1:-1:-1;;;;;39331:6:0;45674:10;:21;;:45;;-1:-1:-1;45713:6:0;;-1:-1:-1;;;;;45713:6:0;45699:10;:20;45674:45;45666:66;;;;-1:-1:-1;;;45666:66:0;;;;;;;:::i;:::-;91083:8:::1;:6;:8::i;:::-;91104:19;:17;:19::i;46182:123::-:0;46257:14;;:40;;-1:-1:-1;;;46257:40:0;;46291:4;46257:40;;;160:51:1;46230:7:0;;-1:-1:-1;;;;;46257:14:0;;:25;;133:18:1;;46257:40:0;14:203:1;86614:515:0;39144:13;:11;:13::i;:::-;86719:37:::1;86759:33;86772:19;86759:12;:33::i;:::-;86719:73;;86803:13;86819:20;86840:1;86819:23;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;86870:4:::1;::::0;86819:23;;-1:-1:-1;;;;;;86870:4:0;;::::1;86861:13:::0;;::::1;::::0;86853:31:::1;;;::::0;-1:-1:-1;;;86853:31:0;;9323:2:1;86853:31:0::1;::::0;::::1;9305:21:1::0;9362:1;9342:18;;;9335:29;-1:-1:-1;;;9380:18:1;;;9373:35;9425:18;;86853:31:0::1;9121:328:1::0;86853:31:0::1;86912:12;::::0;-1:-1:-1;;;;;86912:12:0;;::::1;86903:21:::0;;::::1;::::0;86895:40:::1;;;::::0;-1:-1:-1;;;86895:40:0;;9656:2:1;86895:40:0::1;::::0;::::1;9638:21:1::0;9695:1;9675:18;;;9668:29;-1:-1:-1;;;9713:18:1;;;9706:36;9759:18;;86895:40:0::1;9454:329:1::0;86895:40:0::1;86961:46;::::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;;;;;86961:46:0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;;86948:7:::1;:60:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;86948:60:0;;;;;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;-1:-1:-1;;;;;;86948:60:0::1;::::0;;;::::1;;::::0;;;;86961:46;;86948:60;;;;;;;::::1;::::0;;::::1;:::i;:::-;-1:-1:-1::0;86948:60:0::1;::::0;;;::::1;::::0;::::1;::::0;;::::1;::::0;87045:9;87019:39:::1;::::0;-1:-1:-1;;;;;87019:25:0;;::::1;::::0;87045:9:::1;;87019:25;:39::i;:::-;87095:9;::::0;87069:52:::1;::::0;-1:-1:-1;;;;;87069:25:0;;::::1;::::0;87095:9:::1;-1:-1:-1::0;;87069:25:0::1;:52::i;47545:190::-:0;39144:13;:11;:13::i;:::-;47633:17:::1;:38:::0;;-1:-1:-1;;;;;;47633:38:0::1;-1:-1:-1::0;;;;;47633:38:0;::::1;::::0;;::::1;::::0;;;47687:40:::1;::::0;160:51:1;;;47687:40:0::1;::::0;148:2:1;133:18;47687:40:0::1;14:203:1::0;46503:190:0;39304:7;39331:6;-1:-1:-1;;;;;39331:6:0;45674:10;:21;;:45;;-1:-1:-1;45713:6:0;;-1:-1:-1;;;;;45713:6:0;45699:10;:20;45674:45;45666:66;;;;-1:-1:-1;;;45666:66:0;;;;;;;:::i;:::-;44694:2:::1;46581:4;:26;;46573:43;;;;-1:-1:-1::0;;;46573:43:0::1;;;;;;12188:2:1::0;12170:21;;;12227:1;12207:18;;;12200:29;-1:-1:-1;;;12260:2:1;12245:18;;12238:34;12304:2;12289:18;;11986:327;46573:43:0::1;46627:13;:20:::0;;;46663:22:::1;::::0;1853:25:1;;;46663:22:0::1;::::0;1841:2:1;1826:18;46663:22:0::1;1707:177:1::0;46018:156:0;46063:25;;:::i;:::-;46108:58;;;;;;;;46127:9;:7;:9::i;:::-;46108:58;;;;48035:7;46108:58;;;;46152:13;:11;:13::i;:::-;46108:58;;46101:65;46018:156;-1:-1:-1;46018:156:0:o;79074:28::-;;;;;;;:::i;87471:118::-;87551:4;;87544:37;;-1:-1:-1;;;87544:37:0;;87575:4;87544:37;;;160:51:1;87517:7:0;;-1:-1:-1;;;;;87551:4:0;;87544:22;;133:18:1;;87544:37:0;14:203:1;47284:197:0;47370:10;;-1:-1:-1;;;;;47370:10:0;47356;:24;47348:48;;;;-1:-1:-1;;;47348:48:0;;12520:2:1;47348:48:0;;;12502:21:1;12559:2;12539:18;;;12532:30;-1:-1:-1;;;12578:18:1;;;12571:41;12629:18;;47348:48:0;12318:335:1;47348:48:0;47407:10;:24;;-1:-1:-1;;;;;;47407:24:0;-1:-1:-1;;;;;47407:24:0;;;;;;;;47447:26;;160:51:1;;;47447:26:0;;148:2:1;133:18;47447:26:0;14:203:1;89031:434:0;39304:7;39331:6;-1:-1:-1;;;;;39331:6:0;45674:10;:21;;:45;;-1:-1:-1;45713:6:0;;-1:-1:-1;;;;;45713:6:0;45699:10;:20;45674:45;45666:66;;;;-1:-1:-1;;;45666:66:0;;;;;;;:::i;:::-;89132:29:::1;89164:30;89177:16;89164:12;:30::i;:::-;89232:3;::::0;89213:15;;89132:62;;-1:-1:-1;;;;;;89232:3:0::1;::::0;89132:62;;89232:3:::1;::::0;89213:15:::1;;;;:::i;:::-;;;;;;;-1:-1:-1::0;;;;;89213:22:0::1;;89205:39;;;;-1:-1:-1::0;;;89205:39:0::1;;;;;;12860:2:1::0;12842:21;;;12899:1;12879:18;;;12872:29;-1:-1:-1;;;12932:2:1;12917:18;;12910:34;12976:2;12961:18;;12658:327;89205:39:0::1;89304:6;::::0;89276:19;;-1:-1:-1;;;;;89304:6:0;;::::1;::::0;89263:12;;89276:23:::1;::::0;89304:6;;89276:23:::1;:::i;:::-;89263:37;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1::0;;;;;89263:47:0::1;;89255:67;;;::::0;-1:-1:-1;;;89255:67:0;;13192:2:1;89255:67:0::1;::::0;::::1;13174:21:1::0;13231:1;13211:18;;;13204:29;-1:-1:-1;;;13249:18:1;;;13242:37;13296:18;;89255:67:0::1;12990:330:1::0;89255:67:0::1;89335:19;:17;:19::i;:::-;89365:15;:34;89383:16:::0;89365:15;:34:::1;:::i;:::-;-1:-1:-1::0;89410:9:0::1;:19:::0;;-1:-1:-1;;;;;;89410:19:0::1;;-1:-1:-1::0;;;;;89410:19:0;::::1;;;::::0;;89440:17:::1;:15;:17::i;:::-;89121:344;89031:434:::0;;:::o;81168:254::-;41999:19;:17;:19::i;:::-;81244:4:::1;::::0;81237:37:::1;::::0;-1:-1:-1;;;81237:37:0;;81268:4:::1;81237:37;::::0;::::1;160:51:1::0;81219:15:0::1;::::0;-1:-1:-1;;;;;81244:4:0::1;::::0;81237:22:::1;::::0;133:18:1;;81237:37:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;81219:55:::0;-1:-1:-1;81291:11:0;;81287:128:::1;;81333:12;::::0;81319:44:::1;::::0;-1:-1:-1;;;81319:44:0;;::::1;::::0;::::1;1853:25:1::0;;;-1:-1:-1;;;;;81333:12:0;;::::1;::::0;81319:35:::1;::::0;1826:18:1;;81319:44:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;81383:20;81391:11;:9;:11::i;:::-;81383:20;::::0;1853:25:1;;;1841:2;1826:18;81383:20:0::1;1707:177:1::0;82569:85:0;39304:7;39331:6;-1:-1:-1;;;;;39331:6:0;45674:10;:21;;:45;;-1:-1:-1;45713:6:0;;-1:-1:-1;;;;;45713:6:0;45699:10;:20;45674:45;45666:66;;;;-1:-1:-1;;;45666:66:0;;;;;;;:::i;46904:142::-;39144:13;:11;:13::i;:::-;46976:9:::1;:22:::0;;-1:-1:-1;;;;;;46976:22:0::1;-1:-1:-1::0;;;;;46976:22:0;::::1;::::0;;::::1;::::0;;;47014:24:::1;::::0;160:51:1;;;47014:24:0::1;::::0;148:2:1;133:18;47014:24:0::1;14:203:1::0;88540:130:0;88589:16;88625:37;88638:7;88646:1;88638:10;;;;;;;;:::i;:::-;;;;;;;;;;;:23;;88625:37;;;;;:::i;89473:115::-;39144:13;:11;:13::i;:::-;89550::::1;:30:::0;;;::::1;;-1:-1:-1::0;;;89550:30:0::1;-1:-1:-1::0;;;;89550:30:0;;::::1;::::0;;;::::1;::::0;;89473:115::o;89900:148::-;89990:12;;90036:3;;89976:64;;-1:-1:-1;;;89976:64:0;;90029:4;89976:64;;;13537:34:1;-1:-1:-1;;;;;90036:3:0;;;13587:18:1;;;13580:43;89949:7:0;;89990:12;;;;;89976:44;;13472:18:1;;89976:64:0;13325:304:1;48079:115:0;48131:7;42465;;-1:-1:-1;;;42465:7:0;;;;48158:28;;-1:-1:-1;48173:13:0;;;87673:133::o;48158:28::-;-1:-1:-1;48169:1:0;;48079:115::o;40164:201::-;39144:13;:11;:13::i;:::-;-1:-1:-1;;;;;40253:22:0;::::1;40245:73;;;::::0;-1:-1:-1;;;40245:73:0;;13836:2:1;40245:73:0::1;::::0;::::1;13818:21:1::0;13875:2;13855:18;;;13848:30;13914:34;13894:18;;;13887:62;-1:-1:-1;;;13965:18:1;;;13958:36;14011:19;;40245:73:0::1;13634:402:1::0;40245:73:0::1;40329:28;40348:8;40329:18;:28::i;79300:23::-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;79300:23:0;;;;-1:-1:-1;79300:23:0;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;90316:133::-;39304:7;39331:6;-1:-1:-1;;;;;39331:6:0;45674:10;:21;;:45;;-1:-1:-1;45713:6:0;;-1:-1:-1;;;;;45713:6:0;45699:10;:20;45674:45;45666:66;;;;-1:-1:-1;;;45666:66:0;;;;;;;:::i;:::-;90403:17:::1;:38:::0;;-1:-1:-1;;90403:38:0::1;::::0;::::1;;::::0;;;::::1;::::0;;90316:133::o;90549:271::-;90614:5;;-1:-1:-1;;;;;90614:5:0;90600:10;:19;90592:38;;;;-1:-1:-1;;;90592:38:0;;;;;;;:::i;:::-;90657:12;;-1:-1:-1;;;;;90657:12:0;90643:36;90680:15;:13;:15::i;:::-;90643:53;;;;;;;;;;;;;1853:25:1;;1841:2;1826:18;;1707:177;90643:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;90734:4:0;;90727:37;;-1:-1:-1;;;90727:37:0;;90758:4;90727:37;;;160:51:1;90709:15:0;;-1:-1:-1;;;;;;90734:4:0;;;;-1:-1:-1;90727:22:0;;133:18:1;;90727:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90782:4;;;90797:5;90775:37;;-1:-1:-1;;;90775:37:0;;-1:-1:-1;;;;;90797:5:0;;;90775:37;;;14215:51:1;14282:18;;;14275:34;;;90709:55:0;;-1:-1:-1;90782:4:0;;90775:21;;14188:18:1;;90775:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;90581:239;90549:271::o;88678:136::-;88733:16;88769:37;88782:7;88790:1;88782:10;;;;;;;;:::i;88769:37::-;88762:44;88678:136;-1:-1:-1;;88678:136:0:o;88278:119::-;88324:16;88360:29;88373:15;88360:29;;;;;:::i;69554:238::-;69614:7;68763:20;68650:1;68555:2;68763:20;:::i;:::-;68555:2;69745:4;:11;:23;;;;:::i;:::-;69744:39;;;;:::i;70061:298::-;70153:14;;;70246:17;:4;70153:14;70246;:17::i;:::-;70237:26;-1:-1:-1;70280:24:0;:4;68555:2;70280:13;:24::i;:::-;70274:30;-1:-1:-1;70324:27:0;68763:20;68650:1;68555:2;68763:20;:::i;:::-;70324:4;;:14;:27::i;:::-;70315:36;;70061:298;;;;;:::o;70913:151::-;70974:12;71006:50;68763:20;68650:1;68555:2;68763:20;:::i;:::-;;68650:1;68555:2;68763:20;:::i;:::-;71030:4;:11;:25;;;;:::i;:::-;71006:4;;:50;:10;:50::i;29834:616::-;30198:10;;;30197:62;;-1:-1:-1;30214:39:0;;-1:-1:-1;;;30214:39:0;;30238:4;30214:39;;;13537:34:1;-1:-1:-1;;;;;13607:15:1;;;13587:18;;;13580:43;30214:15:0;;;;;13472:18:1;;30214:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;30197:62;30175:166;;;;-1:-1:-1;;;30175:166:0;;14909:2:1;30175:166:0;;;14891:21:1;14948:2;14928:18;;;14921:30;14987:34;14967:18;;;14960:62;-1:-1:-1;;;15038:18:1;;;15031:52;15100:19;;30175:166:0;14707:418:1;30175:166:0;30379:62;;-1:-1:-1;;;;;14233:32:1;;30379:62:0;;;14215:51:1;14282:18;;;14275:34;;;30352:90:0;;30372:5;;-1:-1:-1;;;30402:22:0;14188:18:1;;30379:62:0;;;;-1:-1:-1;;30379:62:0;;;;;;;;;;;;;;-1:-1:-1;;;;;30379:62:0;-1:-1:-1;;;;;;30379:62:0;;;;;;;;;;30352:19;:90::i;60778:363::-;60857:7;60902:11;:6;60911:2;60902:11;:::i;:::-;60885:6;:13;:28;;60877:62;;;;-1:-1:-1;;;60877:62:0;;15332:2:1;60877:62:0;;;15314:21:1;15371:2;15351:18;;;15344:30;-1:-1:-1;;;15390:18:1;;;15383:51;15451:18;;60877:62:0;15130:345:1;60877:62:0;-1:-1:-1;61031:30:0;61047:4;61031:30;61025:37;-1:-1:-1;;;61021:71:0;;;60778:363::o;61790:375::-;61868:6;61909;61895:10;61909:6;61904:1;61895:10;:::i;:::-;:20;;61887:50;;;;-1:-1:-1;;;61887:50:0;;15682:2:1;61887:50:0;;;15664:21:1;15721:2;15701:18;;;15694:30;-1:-1:-1;;;15740:18:1;;;15733:47;15797:18;;61887:50:0;15480:341:1;61887:50:0;61973:10;:6;61982:1;61973:10;:::i;:::-;61956:6;:13;:27;;61948:60;;;;-1:-1:-1;;;61948:60:0;;16028:2:1;61948:60:0;;;16010:21:1;16067:2;16047:18;;;16040:30;-1:-1:-1;;;16086:18:1;;;16079:50;16146:18;;61948:60:0;15826:344:1;61948:60:0;-1:-1:-1;62089:29:0;62105:3;62089:29;62083:36;;61790:375::o;57991:2779::-;58132:12;58186:7;58170:12;58186:7;58180:2;58170:12;:::i;:::-;:23;;58162:50;;;;-1:-1:-1;;;58162:50:0;;16377:2:1;58162:50:0;;;16359:21:1;16416:2;16396:18;;;16389:30;-1:-1:-1;;;16435:18:1;;;16428:44;16489:18;;58162:50:0;16175:338:1;58162:50:0;58248:16;58257:7;58248:6;:16;:::i;:::-;58231:6;:13;:33;;58223:63;;;;-1:-1:-1;;;58223:63:0;;16720:2:1;58223:63:0;;;16702:21:1;16759:2;16739:18;;;16732:30;-1:-1:-1;;;16778:18:1;;;16771:47;16835:18;;58223:63:0;16518:341:1;58223:63:0;58299:22;58365:15;;58394:1933;;;;60471:4;60465:11;60452:24;;60652:1;60641:9;60634:20;60702:4;60691:9;60687:20;60681:4;60674:34;58358:2365;;58394:1933;58571:4;58565:11;58552:24;;59208:2;59199:7;59195:16;59580:9;59573:17;59567:4;59563:28;59551:9;59540;59536:25;59532:60;59629:7;59625:2;59621:16;59878:6;59864:9;59857:17;59851:4;59847:28;59835:9;59827:6;59823:22;59819:57;59815:70;59657:426;59912:3;59908:2;59905:11;59657:426;;;60054:9;;60043:21;;59954:4;59946:13;;;;59987;59657:426;;;-1:-1:-1;;60103:26:0;;;60307:2;60290:11;-1:-1:-1;;60286:25:0;60280:4;60273:39;-1:-1:-1;58358:2365:0;-1:-1:-1;60753:9:0;-1:-1:-1;57991:2779:0;;;;;;:::o;23811:229::-;23948:12;23980:52;24002:6;24010:4;24016:1;24019:12;23980:21;:52::i;:::-;23973:59;23811:229;-1:-1:-1;;;;23811:229:0:o;82717:666::-;41999:19;:17;:19::i;:::-;82799:12:::1;::::0;-1:-1:-1;;;;;82799:12:0::1;:26:::0;82795:105:::1;;82856:12;::::0;82875::::1;::::0;82842:46:::1;::::0;-1:-1:-1;;;82842:46:0;;-1:-1:-1;;;;;82875:12:0;;::::1;82842:46;::::0;::::1;160:51:1::0;82856:12:0;::::1;::::0;82842:32:::1;::::0;133:18:1;;82842:46:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;82795:105;82924:12;::::0;82910:56:::1;::::0;-1:-1:-1;;;82910:56:0;;82960:4:::1;82910:56;::::0;::::1;160:51:1::0;-1:-1:-1;;;;;82924:12:0;;::::1;::::0;82910:41:::1;::::0;133:18:1;;82910:56:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;82977:21;:19;:21::i;:::-;83036:6;::::0;83029:39:::1;::::0;-1:-1:-1;;;83029:39:0;;83062:4:::1;83029:39;::::0;::::1;160:51:1::0;83009:17:0::1;::::0;-1:-1:-1;;;;;83036:6:0::1;::::0;83029:24:::1;::::0;133:18:1;;83029:39:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;83009:59:::0;-1:-1:-1;83083:13:0;;83079:297:::1;;83113:28;83124:16;83113:10;:28::i;:::-;83156:14;:12;:14::i;:::-;83185:21;83209:15;:13;:15::i;:::-;83185:39;;83239:9;:7;:9::i;:::-;83277:15;83263:11;:29:::0;83325:10:::1;83312:52;83337:13:::0;83352:11:::1;:9;:11::i;:::-;83312:52;::::0;;17038:25:1;;;17094:2;17079:18;;17072:34;;;;17011:18;83312:52:0::1;;;;;;;83098:278;82784:599;82717:666:::0;:::o;39423:132::-;39304:7;39331:6;-1:-1:-1;;;;;39331:6:0;4404:10;39487:23;39479:68;;;;-1:-1:-1;;;39479:68:0;;17319:2:1;39479:68:0;;;17301:21:1;;;17338:18;;;17331:30;17397:34;17377:18;;;17370:62;17449:18;;39479:68:0;17117:356:1;29098:211:0;29242:58;;-1:-1:-1;;;;;14233:32:1;;29242:58:0;;;14215:51:1;14282:18;;;14275:34;;;29215:86:0;;29235:5;;-1:-1:-1;;;29265:23:0;14188:18:1;;29242:58:0;14041:274:1;87814:456:0;87879:16;87908:13;87924:16;:5;:14;:16::i;:::-;87908:32;-1:-1:-1;87951:22:0;87990:12;87908:32;88001:1;87990:12;:::i;:::-;87976:27;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;87976:27:0;;87951:52;;88019:6;88014:226;88031:8;88027:1;:12;88014:226;;;88062:14;88078;88097:23;:5;:21;:23::i;:::-;88061:59;;;;;88146:6;88135:5;88141:1;88135:8;;;;;;;;:::i;:::-;-1:-1:-1;;;;;88135:17:0;;;:8;;;;;;;;;;;:17;88182:6;88167:5;88173;:1;88177;88173:5;:::i;:::-;88167:12;;;;;;;;:::i;:::-;;;;;;:21;-1:-1:-1;;;;;88167:21:0;;;-1:-1:-1;;;;;88167:21:0;;;;;88211:17;:5;:15;:17::i;:::-;88203:25;;88046:194;;88041:3;;;;;:::i;:::-;;;;88014:226;;;-1:-1:-1;88257:5:0;87814:456;-1:-1:-1;;;87814:456:0:o;43249:120::-;42258:16;:14;:16::i;:::-;43318:5:::1;43308:15:::0;;-1:-1:-1;;;;43308:15:0::1;::::0;;43339:22:::1;4404:10:::0;43348:12:::1;43339:22;::::0;-1:-1:-1;;;;;178:32:1;;;160:51;;148:2;133:18;43339:22:0::1;;;;;;;43249:120::o:0;91268:299::-;91340:12;;91322:4;;91315:54;;-1:-1:-1;;;;;91322:4:0;;;;91340:12;-1:-1:-1;;91315:24:0;:54::i;:::-;91407:9;;91387:6;;91380:53;;-1:-1:-1;;;;;91387:6:0;;;;91407:9;-1:-1:-1;;91380:26:0;:53::i;:::-;91468:9;;91451:3;;91444:50;;-1:-1:-1;;;;;91451:3:0;;;;91468:9;;;;;-1:-1:-1;;91444:23:0;:50::i;:::-;91538:4;;91512:12;;91505:54;;-1:-1:-1;;;;;91512:12:0;;;;91538:4;-1:-1:-1;;91505:32:0;:54::i;40525:191::-;40599:16;40618:6;;-1:-1:-1;;;;;40635:17:0;;;-1:-1:-1;;;;;;40635:17:0;;;;;;40668:40;;40618:6;;;;;;;40668:40;;40599:16;40668:40;40588:128;40525:191;:::o;42990:118::-;41999:19;:17;:19::i;:::-;43050:7:::1;:14:::0;;-1:-1:-1;;;;43050:14:0::1;-1:-1:-1::0;;;43050:14:0::1;::::0;;43080:20:::1;43087:12;4404:10:::0;;4324:98;91575:249;91649:12;;91631:4;;91624:41;;-1:-1:-1;;;;;91631:4:0;;;;91649:12;;91624:24;:41::i;:::-;91703:9;;91683:6;;91676:40;;-1:-1:-1;;;;;91683:6:0;;;;91703:9;;91676:26;:40::i;:::-;91751:9;;91734:3;;91727:37;;-1:-1:-1;;;;;91734:3:0;;;;91751:9;;;;;91762:1;91727:23;:37::i;:::-;91808:4;;91782:12;;91775:41;;-1:-1:-1;;;;;91782:12:0;;;;91808:4;;91775:32;:41::i;45800:136::-;45842:29;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45842:29:0;45891:14;;:37;;-1:-1:-1;;;45891:37:0;;45922:4;45891:37;;;160:51:1;-1:-1:-1;;;;;45891:14:0;;;;:22;;133:18:1;;45891:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;45891:37:0;;;;;;;;;;;;:::i;42553:108::-;42441:4;42465:7;-1:-1:-1;;;42465:7:0;;;;42623:9;42615:38;;;;-1:-1:-1;;;42615:38:0;;19045:2:1;42615:38:0;;;19027:21:1;19084:2;19064:18;;;19057:30;-1:-1:-1;;;19103:18:1;;;19096:46;19159:18;;42615:38:0;18843:340:1;32165:716:0;32589:23;32615:69;32643:4;32615:69;;;;;;;;;;;;;;;;;32623:5;-1:-1:-1;;;;;32615:27:0;;;:69;;;;;:::i;:::-;32699:17;;32589:95;;-1:-1:-1;32699:21:0;32695:179;;32796:10;32785:30;;;;;;;;;;;;:::i;:::-;32777:85;;;;-1:-1:-1;;;32777:85:0;;19390:2:1;32777:85:0;;;19372:21:1;19429:2;19409:18;;;19402:30;19468:34;19448:18;;;19441:62;-1:-1:-1;;;19519:18:1;;;19512:40;19569:19;;32777:85:0;19188:406:1;24931:510:0;25101:12;25159:5;25134:21;:30;;25126:81;;;;-1:-1:-1;;;25126:81:0;;19801:2:1;25126:81:0;;;19783:21:1;19840:2;19820:18;;;19813:30;19879:34;19859:18;;;19852:62;-1:-1:-1;;;19930:18:1;;;19923:36;19976:19;;25126:81:0;19599:402:1;25126:81:0;-1:-1:-1;;;;;21361:19:0;;;25218:60;;;;-1:-1:-1;;;25218:60:0;;20208:2:1;25218:60:0;;;20190:21:1;20247:2;20227:18;;;20220:30;20286:31;20266:18;;;20259:59;20335:18;;25218:60:0;20006:353:1;25218:60:0;25292:12;25306:23;25333:6;-1:-1:-1;;;;;25333:11:0;25352:5;25359:4;25333:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25291:73;;;;25382:51;25399:7;25408:10;25420:12;25382:16;:51::i;:::-;25375:58;24931:510;-1:-1:-1;;;;;;;24931:510:0:o;83574:519::-;83649:3;;83642:36;;-1:-1:-1;;;83642:36:0;;83672:4;83642:36;;;160:51:1;83625:14:0;;-1:-1:-1;;;;;83649:3:0;;83642:21;;133:18:1;;83642:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;83693:10;;83625:53;;-1:-1:-1;83693:10:0;;:24;;;;;83716:1;83707:6;:10;83693:24;83689:124;;;83734:67;83766:9;;;;;;;;;-1:-1:-1;;;;;83766:9:0;83777:15;83734:67;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83794:6;83734:31;:67::i;:::-;;83689:124;83847:6;83842:244;83859:7;:14;83855:18;;83842:244;;;83895:8;83913:7;83921:1;83913:10;;;;;;;;:::i;:::-;;;;;;;;;;;;;;:16;83906:49;;-1:-1:-1;;;83906:49:0;;83949:4;83906:49;;;160:51:1;-1:-1:-1;;;;;83913:16:0;;;;83906:34;;133:18:1;;83906:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;83895:60;;83981:7;83989:1;83981:10;;;;;;;;:::i;:::-;;;;;;;;;;;:20;;;83974:3;:27;83970:105;;84022:37;84030:7;84038:1;84030:10;;;;;;;;:::i;:::-;;;;;;;;;;;:23;;84022:37;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84055:3;84022:7;:37::i;:::-;;83970:105;-1:-1:-1;83875:3:0;;;;:::i;:::-;;;;83842:244;;84126:727;84192:34;84229:9;:7;:9::i;:::-;84311:10;;84276:6;;84269:39;;-1:-1:-1;;;84269:39:0;;84302:4;84269:39;;;160:51:1;84311:10:0;;-1:-1:-1;84249:17:0;;44635:7;;84311:10;-1:-1:-1;;;;;84276:6:0;;84269:24;;133:18:1;;84269:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:52;;;;:::i;:::-;:62;;;;:::i;:::-;84249:82;;84344:21;44635:7;84380:4;:9;;;84368;:21;;;;:::i;:::-;:31;;;;:::i;:::-;84417:6;;84344:55;;-1:-1:-1;84410:60:0;;-1:-1:-1;;;;;84417:6:0;84438:16;84344:55;84410:27;:60::i;:::-;84483:22;44635:7;84520:4;:10;;;84508:9;:22;;;;:::i;:::-;:32;;;;:::i;:::-;84579:17;;84558:6;;84483:57;;-1:-1:-1;84551:62:0;;-1:-1:-1;;;;;84558:6:0;;;;84579:17;84483:57;84551:27;:62::i;:::-;84626:27;44635:7;84668:4;:15;;;84656:9;:27;;;;:::i;:::-;:37;;;;:::i;:::-;84732:10;;84711:6;;84626:67;;-1:-1:-1;84704:60:0;;-1:-1:-1;;;;;84711:6:0;;;;84732:10;84626:67;84704:27;:60::i;:::-;84782:63;;;20845:25:1;;;20901:2;20886:18;;20879:34;;;20929:18;;;20922:34;;;84782:63:0;;20833:2:1;20818:18;84782:63:0;;;;;;;84181:672;;;;;84126:727;:::o;84916:1690::-;85054:6;;85047:39;;-1:-1:-1;;;85047:39:0;;85080:4;85047:39;;;160:51:1;84960:18:0;;;;;;-1:-1:-1;;;;;85054:6:0;;85047:24;;133:18:1;;85047:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;85117:6;;85101:12;;85027:59;;-1:-1:-1;;;;;;85101:12:0;;;85117:6;;85101:22;85097:392;;85140:39;85148:19;85140:39;;;;;:::i;:::-;-1:-1:-1;85214:12:0;;85207:45;;-1:-1:-1;;;85207:45:0;;85246:4;85207:45;;;160:51:1;-1:-1:-1;;;;;85214:12:0;;;;85207:30;;133:18:1;;85207:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;85194:58;;85097:392;;;85326:13;;85298:9;;-1:-1:-1;85298:9:0;;-1:-1:-1;;;85326:13:0;;;;85322:156;;;85425:6;;85410:52;;-1:-1:-1;;;85410:52:0;;;;;1853:25:1;;;85382:9:0;;-1:-1:-1;85382:9:0;;-1:-1:-1;;;;;85425:6:0;;;;85410:31;;1826:18:1;;85410:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85322:156;85505:8;;85517:1;85505:13;85501:1098;;85535:25;;:::i;:::-;85599:10;85575:7;85583:12;;85575:21;;;;;;;:::i;:::-;;;;:34;85628:13;;;;85624:157;;;85654:4;;85643:48;;-1:-1:-1;;;85643:48:0;;-1:-1:-1;;;;;85654:4:0;;;;85643:30;;:48;;85674:7;;85654:4;;;;85643:48;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85624:157;;;85722:4;;85711:70;;-1:-1:-1;;;85711:70:0;;-1:-1:-1;;;;;85722:4:0;;;;85711:30;;85749:19;;85711:70;;85770:7;;85722:4;;85711:70;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85520:273;89121:344:::1;89031:434:::0;;:::o;85501:1098::-;85803:8;;85815:1;85803:13;85799:800;;85833:25;;:::i;:::-;85897:10;85873:7;85881:12;;85873:21;;;;;;;:::i;:::-;;;;:34;85926:13;;;;85922:214;;;85952:4;;85941:48;;-1:-1:-1;;;85941:48:0;;-1:-1:-1;;;;;85952:4:0;;;;85941:30;;:48;;85972:7;;85952:4;;;;85941:48;;;:::i;85922:214::-;86013:11;;;;;;;86009:127;;;86037:4;;86057;;86026:48;;-1:-1:-1;;;86026:48:0;;-1:-1:-1;;;;;86037:4:0;;;;86026:30;;:48;;86057:4;;;86063:7;;86037:4;;86026:48;;;:::i;86009:127::-;86105:4;;86094:42;;-1:-1:-1;;;86094:42:0;;-1:-1:-1;;;;;86105:4:0;;;;86094:30;;:42;;86125:7;;86105:4;;86094:42;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85818:330;89121:344:::1;89031:434:::0;;:::o;85799:800::-;86158:8;;86170:1;86158:13;86154:445;;86188:25;;:::i;:::-;86252:10;86228:7;86236:12;;86228:21;;;;;;;:::i;:::-;;;;:34;86281:11;;;;;;;86277:127;;;86305:4;;86325;;86294:48;;-1:-1:-1;;;86294:48:0;;-1:-1:-1;;;;;86305:4:0;;;;86294:30;;:48;;86325:4;;;86331:7;;86305:4;;86294:48;;;:::i;86277:127::-;86373:4;;86362:42;;-1:-1:-1;;;86362:42:0;;-1:-1:-1;;;;;86373:4:0;;;;86362:30;;:42;;86393:7;;86373:4;;86362:42;;;:::i;86154:445::-;86426:8;;86438:1;86426:13;86422:177;;86456:25;;:::i;:::-;86520:10;86496:7;86504:12;;86496:21;;;;;;;:::i;:::-;;;;:34;86556:4;;86545:42;;-1:-1:-1;;;86545:42:0;;-1:-1:-1;;;;;86556:4:0;;;;86545:30;;:42;;86576:7;;86556:4;;86545:42;;;:::i;42738:108::-;42441:4;42465:7;-1:-1:-1;;;42465:7:0;;;;42797:41;;;;-1:-1:-1;;;42797:41:0;;25478:2:1;42797:41:0;;;25460:21:1;25517:2;25497:18;;;25490:30;-1:-1:-1;;;25536:18:1;;;25529:50;25596:18;;42797:41:0;25276:344:1;27617:762:0;27767:12;27796:7;27792:580;;;-1:-1:-1;27827:10:0;27820:17;;27792:580;27941:17;;:21;27937:424;;28189:10;28183:17;28250:15;28237:10;28233:2;28229:19;28222:44;27937:424;28332:12;28325:20;;-1:-1:-1;;;28325:20:0;;;;;;;;:::i;77309:511::-;77505:229;;;;;;;;;;;77611:4;77505:229;;;;77641:15;77505:229;;;;;;;;;;77409:17;77505:229;;;;;;77752:60;;-1:-1:-1;;;77752:60:0;;-1:-1:-1;;;;;77752:48:0;;;;;:60;;77505:229;;77752:60;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;77745:67;77309:511;-1:-1:-1;;;;;77309:511:0:o;83391:175::-;83532:9;;83463:17;;83500:58;;-1:-1:-1;;;;;83532:9:0;83543:5;83550:7;83500:31;:58::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;222:258:1;294:1;304:113;318:6;315:1;312:13;304:113;;;394:11;;;388:18;375:11;;;368:39;340:2;333:10;304:113;;;435:6;432:1;429:13;426:48;;;-1:-1:-1;;470:1:1;452:16;;445:27;222:258::o;485:257::-;526:3;564:5;558:12;591:6;586:3;579:19;607:63;663:6;656:4;651:3;647:14;640:4;633:5;629:16;607:63;:::i;:::-;724:2;703:15;-1:-1:-1;;699:29:1;690:39;;;;731:4;686:50;;485:257;-1:-1:-1;;485:257:1:o;747:217::-;894:2;883:9;876:21;857:4;914:44;954:2;943:9;939:18;931:6;914:44;:::i;969:173::-;1037:20;;-1:-1:-1;;;;;1086:31:1;;1076:42;;1066:70;;1132:1;1129;1122:12;1066:70;969:173;;;:::o;1147:186::-;1206:6;1259:2;1247:9;1238:7;1234:23;1230:32;1227:52;;;1275:1;1272;1265:12;1227:52;1298:29;1317:9;1298:29;:::i;1338:118::-;1424:5;1417:13;1410:21;1403:5;1400:32;1390:60;;1446:1;1443;1436:12;1461:241;1517:6;1570:2;1558:9;1549:7;1545:23;1541:32;1538:52;;;1586:1;1583;1576:12;1538:52;1625:9;1612:23;1644:28;1666:5;1644:28;:::i;1889:180::-;1948:6;2001:2;1989:9;1980:7;1976:23;1972:32;1969:52;;;2017:1;2014;2007:12;1969:52;-1:-1:-1;2040:23:1;;1889:180;-1:-1:-1;1889:180:1:o;2074:658::-;2245:2;2297:21;;;2367:13;;2270:18;;;2389:22;;;2216:4;;2245:2;2468:15;;;;2442:2;2427:18;;;2216:4;2511:195;2525:6;2522:1;2519:13;2511:195;;;2590:13;;-1:-1:-1;;;;;2586:39:1;2574:52;;2681:15;;;;2646:12;;;;2622:1;2540:9;2511:195;;;-1:-1:-1;2723:3:1;;2074:658;-1:-1:-1;;;;;;2074:658:1:o;3156:127::-;3217:10;3212:3;3208:20;3205:1;3198:31;3248:4;3245:1;3238:15;3272:4;3269:1;3262:15;3288:253;3360:2;3354:9;3402:4;3390:17;;3437:18;3422:34;;3458:22;;;3419:62;3416:88;;;3484:18;;:::i;:::-;3520:2;3513:22;3288:253;:::o;3546:275::-;3617:2;3611:9;3682:2;3663:13;;-1:-1:-1;;3659:27:1;3647:40;;3717:18;3702:34;;3738:22;;;3699:62;3696:88;;;3764:18;;:::i;:::-;3800:2;3793:22;3546:275;;-1:-1:-1;3546:275:1:o;3826:186::-;3874:4;3907:18;3899:6;3896:30;3893:56;;;3929:18;;:::i;:::-;-1:-1:-1;3995:2:1;3974:15;-1:-1:-1;;3970:29:1;4001:4;3966:40;;3826:186::o;4017:462::-;4059:5;4112:3;4105:4;4097:6;4093:17;4089:27;4079:55;;4130:1;4127;4120:12;4079:55;4166:6;4153:20;4197:48;4213:31;4241:2;4213:31;:::i;:::-;4197:48;:::i;:::-;4270:2;4261:7;4254:19;4316:3;4309:4;4304:2;4296:6;4292:15;4288:26;4285:35;4282:55;;;4333:1;4330;4323:12;4282:55;4398:2;4391:4;4383:6;4379:17;4372:4;4363:7;4359:18;4346:55;4446:1;4421:16;;;4439:4;4417:27;4410:38;;;;4425:7;4017:462;-1:-1:-1;;;4017:462:1:o;4484:388::-;4561:6;4569;4622:2;4610:9;4601:7;4597:23;4593:32;4590:52;;;4638:1;4635;4628:12;4590:52;4678:9;4665:23;4711:18;4703:6;4700:30;4697:50;;;4743:1;4740;4733:12;4697:50;4766:49;4807:7;4798:6;4787:9;4783:22;4766:49;:::i;:::-;4756:59;4862:2;4847:18;;;;4834:32;;-1:-1:-1;;;;4484:388:1:o;4877:939::-;5056:2;5045:9;5038:21;5019:4;5094:6;5088:13;5137:4;5132:2;5121:9;5117:18;5110:32;5185:12;5179:19;5173:3;5162:9;5158:19;5151:48;5260:2;5246:12;5242:21;5236:28;5230:3;5219:9;5215:19;5208:57;5327:4;5313:12;5309:23;5303:30;5296:4;5285:9;5281:20;5274:60;5395:4;5381:12;5377:23;5371:30;5365:3;5354:9;5350:19;5343:59;5457:3;5443:12;5439:22;5433:29;5499:4;5493:3;5482:9;5478:19;5471:33;5527:53;5575:3;5564:9;5560:19;5544:14;5527:53;:::i;:::-;5513:67;;5655:3;5641:12;5637:22;5631:29;5624:37;5617:45;5611:3;5600:9;5596:19;5589:74;5719:2;5711:6;5707:15;5701:22;5694:4;5683:9;5679:20;5672:52;5780:4;5772:6;5768:17;5762:24;5755:4;5744:9;5740:20;5733:54;5804:6;5796:14;;;;4877:939;;;;:::o;5821:394::-;5898:6;5906;5959:2;5947:9;5938:7;5934:23;5930:32;5927:52;;;5975:1;5972;5965:12;5927:52;5998:29;6017:9;5998:29;:::i;:::-;5988:39;;6078:2;6067:9;6063:18;6050:32;6105:18;6097:6;6094:30;6091:50;;;6137:1;6134;6127:12;6091:50;6160:49;6201:7;6192:6;6181:9;6177:22;6160:49;:::i;:::-;6150:59;;;5821:394;;;;;:::o;6220:385::-;-1:-1:-1;;;;;6423:32:1;;6405:51;;6492:2;6487;6472:18;;6465:30;;;-1:-1:-1;;6512:44:1;;6537:18;;6529:6;6512:44;:::i;:::-;6504:52;;6592:6;6587:2;6576:9;6572:18;6565:34;6220:385;;;;;;:::o;6610:380::-;6689:1;6685:12;;;;6732;;;6753:61;;6807:4;6799:6;6795:17;6785:27;;6753:61;6860:2;6852:6;6849:14;6829:18;6826:38;6823:161;;6906:10;6901:3;6897:20;6894:1;6887:31;6941:4;6938:1;6931:15;6969:4;6966:1;6959:15;6823:161;;6610:380;;;:::o;6995:184::-;7065:6;7118:2;7106:9;7097:7;7093:23;7089:32;7086:52;;;7134:1;7131;7124:12;7086:52;-1:-1:-1;7157:16:1;;6995:184;-1:-1:-1;6995:184:1:o;7529:331::-;7731:2;7713:21;;;7770:1;7750:18;;;7743:29;-1:-1:-1;;;7803:2:1;7788:18;;7781:38;7851:2;7836:18;;7529:331::o;7865:329::-;8067:2;8049:21;;;8106:1;8086:18;;;8079:29;-1:-1:-1;;;8139:2:1;8124:18;;8117:36;8185:2;8170:18;;7865:329::o;8199:127::-;8260:10;8255:3;8251:20;8248:1;8241:31;8291:4;8288:1;8281:15;8315:4;8312:1;8305:15;8331:125;8371:4;8399:1;8396;8393:8;8390:34;;;8404:18;;:::i;:::-;-1:-1:-1;8441:9:1;;8331:125::o;8461:168::-;8501:7;8567:1;8563;8559:6;8555:14;8552:1;8549:21;8544:1;8537:9;8530:17;8526:45;8523:71;;;8574:18;;:::i;:::-;-1:-1:-1;8614:9:1;;8461:168::o;8634:217::-;8674:1;8700;8690:132;;8744:10;8739:3;8735:20;8732:1;8725:31;8779:4;8776:1;8769:15;8807:4;8804:1;8797:15;8690:132;-1:-1:-1;8836:9:1;;8634:217::o;8856:128::-;8896:3;8927:1;8923:6;8920:1;8917:13;8914:39;;;8933:18;;:::i;:::-;-1:-1:-1;8969:9:1;;8856:128::o;8989:127::-;9050:10;9045:3;9041:20;9038:1;9031:31;9081:4;9078:1;9071:15;9105:4;9102:1;9095:15;9913:544;10014:2;10009:3;10006:11;10003:448;;;10050:1;10075:5;10071:2;10064:17;10120:4;10116:2;10106:19;10190:2;10178:10;10174:19;10171:1;10167:27;10161:4;10157:38;10226:4;10214:10;10211:20;10208:47;;;-1:-1:-1;10249:4:1;10208:47;10304:2;10299:3;10295:12;10292:1;10288:20;10282:4;10278:31;10268:41;;10359:82;10377:2;10370:5;10367:13;10359:82;;;10422:17;;;10403:1;10392:13;10359:82;;;10363:3;;;9913:544;;;:::o;10633:1348::-;10757:3;10751:10;10784:18;10776:6;10773:30;10770:56;;;10806:18;;:::i;:::-;10835:96;10924:6;10884:38;10916:4;10910:11;10884:38;:::i;:::-;10878:4;10835:96;:::i;:::-;10986:4;;11050:2;11039:14;;11067:1;11062:662;;;;11768:1;11785:6;11782:89;;;-1:-1:-1;11837:19:1;;;11831:26;11782:89;-1:-1:-1;;10590:1:1;10586:11;;;10582:24;10578:29;10568:40;10614:1;10610:11;;;10565:57;11884:81;;11032:943;;11062:662;9860:1;9853:14;;;9897:4;9884:18;;-1:-1:-1;;11098:20:1;;;11215:236;11229:7;11226:1;11223:14;11215:236;;;11318:19;;;11312:26;11297:42;;11410:27;;;;11378:1;11366:14;;;;11245:19;;11215:236;;;11219:3;11479:6;11470:7;11467:19;11464:201;;;11540:19;;;11534:26;-1:-1:-1;;11623:1:1;11619:14;;;11635:3;11615:24;11611:37;11607:42;11592:58;11577:74;;11464:201;-1:-1:-1;;;;;11711:1:1;11695:14;;;11691:22;11678:36;;-1:-1:-1;10633:1348:1:o;14320:132::-;14396:13;;14418:28;14396:13;14418:28;:::i;14457:245::-;14524:6;14577:2;14565:9;14556:7;14552:23;14548:32;14545:52;;;14593:1;14590;14583:12;14545:52;14625:9;14619:16;14644:28;14666:5;14644:28;:::i;17478:135::-;17517:3;17538:17;;;17535:43;;17558:18;;:::i;:::-;-1:-1:-1;17605:1:1;17594:13;;17478:135::o;17618:1220::-;17717:6;17748:2;17791;17779:9;17770:7;17766:23;17762:32;17759:52;;;17807:1;17804;17797:12;17759:52;17840:9;17834:16;17869:18;17910:2;17902:6;17899:14;17896:34;;;17926:1;17923;17916:12;17896:34;17949:22;;;;18005:4;17987:16;;;17983:27;17980:47;;;18023:1;18020;18013:12;17980:47;18049:22;;:::i;:::-;18100:2;18094:9;18087:5;18080:24;18150:2;18146;18142:11;18136:18;18131:2;18124:5;18120:14;18113:42;18201:2;18197;18193:11;18187:18;18182:2;18175:5;18171:14;18164:42;18252:2;18248;18244:11;18238:18;18233:2;18226:5;18222:14;18215:42;18296:3;18292:2;18288:12;18282:19;18326:2;18316:8;18313:16;18310:36;;;18342:1;18339;18332:12;18310:36;18365:17;;;-1:-1:-1;18413:4:1;18405:13;;18401:27;-1:-1:-1;18391:55:1;;18442:1;18439;18432:12;18391:55;18471:2;18465:9;18496:48;18512:31;18540:2;18512:31;:::i;18496:48::-;18567:2;18560:5;18553:17;18607:7;18602:2;18597;18593;18589:11;18585:20;18582:33;18579:53;;;18628:1;18625;18618:12;18579:53;18641:54;18692:2;18687;18680:5;18676:14;18671:2;18667;18663:11;18641:54;:::i;:::-;18722:3;18711:15;;18704:30;-1:-1:-1;18767:40:1;18802:3;18794:12;;18767:40;:::i;:::-;18761:3;18750:15;;18743:65;18754:5;17618:1220;-1:-1:-1;;;;;;17618:1220:1:o;20364:274::-;20493:3;20531:6;20525:13;20547:53;20593:6;20588:3;20581:4;20573:6;20569:17;20547:53;:::i;:::-;20616:16;;;;;20364:274;-1:-1:-1;;20364:274:1:o;20967:343::-;21077:5;21100:1;21110:194;21124:4;21121:1;21118:11;21110:194;;;21183:13;;21171:26;;21220:4;21244:12;;;;21279:15;;;;21144:1;21137:9;21110:194;;21315:419;21553:3;21538:19;;21566:60;21542:9;21608:6;21566:60;:::i;:::-;21662:6;21657:2;21646:9;21642:18;21635:34;21719:6;21712:14;21705:22;21700:2;21689:9;21685:18;21678:50;21315:419;;;;;;:::o;21739:337::-;21955:2;21940:18;;21967:60;21944:9;22009:6;21967:60;:::i;:::-;22063:6;22058:2;22047:9;22043:18;22036:34;21739:337;;;;;:::o;22081:::-;22185:5;22208:1;22218:194;22232:4;22229:1;22226:11;22218:194;;;22291:13;;22279:26;;22328:4;22352:12;;;;22387:15;;;;22252:1;22245:9;22218:194;;22423:414;22661:3;22646:19;;22674:54;22650:9;22710:6;22674:54;:::i;:::-;22764:6;22759:2;22748:9;22744:18;22737:34;22822:6;22815:14;22808:22;22802:3;22791:9;22787:19;22780:51;22423:414;;;;;;:::o;22842:430::-;-1:-1:-1;;;;;23117:32:1;;23099:51;;23086:3;23071:19;;23159:63;23218:2;23203:18;;23195:6;23159:63;:::i;:::-;23259:6;23253:3;23242:9;23238:19;23231:35;22842:430;;;;;;:::o;23277:332::-;23493:3;23478:19;;23506:54;23482:9;23542:6;23506:54;:::i;:::-;23596:6;23591:2;23580:9;23576:18;23569:34;23277:332;;;;;:::o;23614:326::-;23707:5;23730:1;23740:194;23754:4;23751:1;23748:11;23740:194;;;23813:13;;23801:26;;23850:4;23874:12;;;;23909:15;;;;23774:1;23767:9;23740:194;;23945:419;-1:-1:-1;;;;;24220:32:1;;24202:51;;24189:3;24174:19;;24262:52;24310:2;24295:18;;24287:6;24262:52;:::i;:::-;24351:6;24345:3;24334:9;24330:19;24323:35;23945:419;;;;;;:::o;24369:322::-;24585:3;24570:19;;24598:43;24574:9;24623:6;24598:43;:::i;:::-;24678:6;24672:3;24661:9;24657:19;24650:35;24369:322;;;;;:::o;24696:575::-;24912:3;24897:19;;24901:9;24993:6;24870:4;25027:194;25041:4;25038:1;25035:11;25027:194;;;25100:13;;25088:26;;25137:4;25161:12;;;;25196:15;;;;25061:1;25054:9;25027:194;;;25031:3;;;25258:6;25252:3;25241:9;25237:19;25230:35;24696:575;;;;;:::o;25849:652::-;26046:2;26035:9;26028:21;26009:4;26084:6;26078:13;26127:4;26122:2;26111:9;26107:18;26100:32;26155:51;26201:3;26190:9;26186:19;26172:12;26155:51;:::i;:::-;26141:65;;26287:1;26283;26278:3;26274:11;26270:19;26264:2;26256:6;26252:15;26246:22;26242:48;26237:2;26226:9;26222:18;26215:76;26345:2;26337:6;26333:15;26327:22;26322:2;26311:9;26307:18;26300:50;26405:2;26397:6;26393:15;26387:22;26381:3;26370:9;26366:19;26359:51;26466:3;26458:6;26454:16;26448:23;26441:4;26430:9;26426:20;26419:53;26489:6;26481:14;;;25849:652;;;;:::o
Swarm Source
ipfs://c6e8711d43030945e7f246f72284c1b4f5b233b65138de79b704169dc817b45c
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.