Source Code
Latest 25 from a total of 52 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Set Col Factor L... | 14479247 | 1428 days ago | IN | 0 ETH | 0.0008029 | ||||
| Deleverage To Mi... | 14479236 | 1428 days ago | IN | 0 ETH | 0.1053817 | ||||
| Leverage To Max | 14272423 | 1461 days ago | IN | 0 ETH | 0.0984809 | ||||
| Harvest | 14272391 | 1461 days ago | IN | 0 ETH | 0.02357986 | ||||
| Harvest | 13681224 | 1552 days ago | IN | 0 ETH | 0.06310011 | ||||
| Harvest | 13210649 | 1626 days ago | IN | 0 ETH | 0.02806309 | ||||
| Leverage To Max | 12944465 | 1667 days ago | IN | 0 ETH | 0.02232951 | ||||
| Harvest | 12944445 | 1667 days ago | IN | 0 ETH | 0.01191949 | ||||
| Harvest | 12925236 | 1670 days ago | IN | 0 ETH | 0.01239057 | ||||
| Harvest | 12771862 | 1694 days ago | IN | 0 ETH | 0.00605871 | ||||
| Harvest | 12734366 | 1700 days ago | IN | 0 ETH | 0.00998877 | ||||
| Harvest | 12657487 | 1712 days ago | IN | 0 ETH | 0.00564877 | ||||
| Leverage To Max | 12644538 | 1714 days ago | IN | 0 ETH | 0.00721554 | ||||
| Harvest | 12644370 | 1714 days ago | IN | 0 ETH | 0.00492693 | ||||
| Set Col Factor L... | 12644370 | 1714 days ago | IN | 0 ETH | 0.00031529 | ||||
| Leverage To Max | 12639920 | 1715 days ago | IN | 0 ETH | 0.02397122 | ||||
| Deleverage To Mi... | 12639708 | 1715 days ago | IN | 0 ETH | 0.03781194 | ||||
| Deleverage To Mi... | 12639703 | 1715 days ago | IN | 0 ETH | 0.03161272 | ||||
| Leverage To Max | 12639635 | 1715 days ago | IN | 0 ETH | 0.00863098 | ||||
| Harvest | 12639597 | 1715 days ago | IN | 0 ETH | 0.0082164 | ||||
| Harvest | 12627041 | 1717 days ago | IN | 0 ETH | 0.0060373 | ||||
| Harvest | 12592394 | 1722 days ago | IN | 0 ETH | 0.00683442 | ||||
| Harvest | 12552295 | 1729 days ago | IN | 0 ETH | 0.01156595 | ||||
| Harvest | 12546044 | 1729 days ago | IN | 0 ETH | 0.01082148 | ||||
| Harvest | 12495175 | 1737 days ago | IN | 0 ETH | 0.02002747 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
StrategyCmpdUsdcV1
Compiler Version
v0.6.7+commit.b8d736ae
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2021-01-17
*/
/**
*Submitted for verification at Etherscan.io on 2020-11-25
*/
pragma solidity ^0.6.2;
// SPDX-License-Identifier: MIT
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
// SPDX-License-Identifier: MIT
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with GSN meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address payable) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}
// File: contracts/GSN/Context.sol
// SPDX-License-Identifier: MIT
// File: contracts/token/ERC20/IERC20.sol
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}
// File: contracts/utils/Address.sol
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// According to EIP-1052, 0x0 is the value returned for not-yet created accounts
// and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
// for accounts without code, i.e. `keccak256('')`
bytes32 codehash;
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
// solhint-disable-next-line no-inline-assembly
assembly { codehash := extcodehash(account) }
return (codehash != accountHash && codehash != 0x0);
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain`call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return _functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
return _functionCallWithValue(target, data, value, errorMessage);
}
function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {
require(isContract(target), "Address: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.call{ value: weiValue }(data);
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
// File: contracts/token/ERC20/ERC20.sol
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* We have followed general OpenZeppelin guidelines: functions revert instead
* of returning `false` on failure. This behavior is nonetheless conventional
* and does not conflict with the expectations of ERC20 applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20 is Context, IERC20 {
using SafeMath for uint256;
using Address for address;
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
uint8 private _decimals;
/**
* @dev Sets the values for {name} and {symbol}, initializes {decimals} with
* a default value of 18.
*
* To select a different value for {decimals}, use {_setupDecimals}.
*
* All three of these values are immutable: they can only be set once during
* construction.
*/
constructor (string memory name, string memory symbol) public {
_name = name;
_symbol = symbol;
_decimals = 18;
}
/**
* @dev Returns the name of the token.
*/
function name() public view returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5,05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is
* called.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view returns (uint8) {
return _decimals;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `recipient` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20};
*
* Requirements:
* - `sender` and `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
* - the caller must have allowance for ``sender``'s tokens of at least
* `amount`.
*/
function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
return true;
}
/**
* @dev Moves tokens `amount` from `sender` to `recipient`.
*
* This is internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `sender` cannot be the zero address.
* - `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
*/
function _transfer(address sender, address recipient, uint256 amount) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
_balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements
*
* - `to` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply = _totalSupply.add(amount);
_balances[account] = _balances[account].add(amount);
emit Transfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
_balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
_totalSupply = _totalSupply.sub(amount);
emit Transfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This 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 Sets {decimals} to a value other than the default one of 18.
*
* WARNING: This function should only be called from the constructor. Most
* applications that interact with token contracts will not expect
* {decimals} to ever change, and may work incorrectly if it does.
*/
function _setupDecimals(uint8 decimals_) internal {
_decimals = decimals_;
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be to transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using SafeMath for uint256;
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
// solhint-disable-next-line max-line-length
require((value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).add(value);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) { // Return data is optional
// solhint-disable-next-line max-line-length
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
/**
* @title Careful Math
* @author Compound
* @notice Derived from OpenZeppelin's SafeMath library
* https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/math/SafeMath.sol
*/
contract CarefulMath {
/**
* @dev Possible error codes that we can return
*/
enum MathError {
NO_ERROR,
DIVISION_BY_ZERO,
INTEGER_OVERFLOW,
INTEGER_UNDERFLOW
}
/**
* @dev Multiplies two numbers, returns an error on overflow.
*/
function mulUInt(uint a, uint b) internal pure returns (MathError, uint) {
if (a == 0) {
return (MathError.NO_ERROR, 0);
}
uint c = a * b;
if (c / a != b) {
return (MathError.INTEGER_OVERFLOW, 0);
} else {
return (MathError.NO_ERROR, c);
}
}
/**
* @dev Integer division of two numbers, truncating the quotient.
*/
function divUInt(uint a, uint b) internal pure returns (MathError, uint) {
if (b == 0) {
return (MathError.DIVISION_BY_ZERO, 0);
}
return (MathError.NO_ERROR, a / b);
}
/**
* @dev Subtracts two numbers, returns an error on overflow (i.e. if subtrahend is greater than minuend).
*/
function subUInt(uint a, uint b) internal pure returns (MathError, uint) {
if (b <= a) {
return (MathError.NO_ERROR, a - b);
} else {
return (MathError.INTEGER_UNDERFLOW, 0);
}
}
/**
* @dev Adds two numbers, returns an error on overflow.
*/
function addUInt(uint a, uint b) internal pure returns (MathError, uint) {
uint c = a + b;
if (c >= a) {
return (MathError.NO_ERROR, c);
} else {
return (MathError.INTEGER_OVERFLOW, 0);
}
}
/**
* @dev add a and b and then subtract c
*/
function addThenSubUInt(uint a, uint b, uint c) internal pure returns (MathError, uint) {
(MathError err0, uint sum) = addUInt(a, b);
if (err0 != MathError.NO_ERROR) {
return (err0, 0);
}
return subUInt(sum, c);
}
}
/**
* @title Exponential module for storing fixed-precision decimals
* @author Compound
* @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.
* Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:
* `Exp({mantissa: 5100000000000000000})`.
*/
contract Exponential is CarefulMath {
uint constant expScale = 1e18;
uint constant doubleScale = 1e36;
uint constant halfExpScale = expScale/2;
uint constant mantissaOne = expScale;
struct Exp {
uint mantissa;
}
struct Double {
uint mantissa;
}
/**
* @dev Creates an exponential from numerator and denominator values.
* Note: Returns an error if (`num` * 10e18) > MAX_INT,
* or if `denom` is zero.
*/
function getExp(uint num, uint denom) pure internal returns (MathError, Exp memory) {
(MathError err0, uint scaledNumerator) = mulUInt(num, expScale);
if (err0 != MathError.NO_ERROR) {
return (err0, Exp({mantissa: 0}));
}
(MathError err1, uint rational) = divUInt(scaledNumerator, denom);
if (err1 != MathError.NO_ERROR) {
return (err1, Exp({mantissa: 0}));
}
return (MathError.NO_ERROR, Exp({mantissa: rational}));
}
/**
* @dev Adds two exponentials, returning a new exponential.
*/
function addExp(Exp memory a, Exp memory b) pure internal returns (MathError, Exp memory) {
(MathError error, uint result) = addUInt(a.mantissa, b.mantissa);
return (error, Exp({mantissa: result}));
}
/**
* @dev Subtracts two exponentials, returning a new exponential.
*/
function subExp(Exp memory a, Exp memory b) pure internal returns (MathError, Exp memory) {
(MathError error, uint result) = subUInt(a.mantissa, b.mantissa);
return (error, Exp({mantissa: result}));
}
/**
* @dev Multiply an Exp by a scalar, returning a new Exp.
*/
function mulScalar(Exp memory a, uint scalar) pure internal returns (MathError, Exp memory) {
(MathError err0, uint scaledMantissa) = mulUInt(a.mantissa, scalar);
if (err0 != MathError.NO_ERROR) {
return (err0, Exp({mantissa: 0}));
}
return (MathError.NO_ERROR, Exp({mantissa: scaledMantissa}));
}
/**
* @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.
*/
function mulScalarTruncate(Exp memory a, uint scalar) pure internal returns (MathError, uint) {
(MathError err, Exp memory product) = mulScalar(a, scalar);
if (err != MathError.NO_ERROR) {
return (err, 0);
}
return (MathError.NO_ERROR, truncate(product));
}
/**
* @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.
*/
function mulScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) pure internal returns (MathError, uint) {
(MathError err, Exp memory product) = mulScalar(a, scalar);
if (err != MathError.NO_ERROR) {
return (err, 0);
}
return addUInt(truncate(product), addend);
}
/**
* @dev Divide an Exp by a scalar, returning a new Exp.
*/
function divScalar(Exp memory a, uint scalar) pure internal returns (MathError, Exp memory) {
(MathError err0, uint descaledMantissa) = divUInt(a.mantissa, scalar);
if (err0 != MathError.NO_ERROR) {
return (err0, Exp({mantissa: 0}));
}
return (MathError.NO_ERROR, Exp({mantissa: descaledMantissa}));
}
/**
* @dev Divide a scalar by an Exp, returning a new Exp.
*/
function divScalarByExp(uint scalar, Exp memory divisor) pure internal returns (MathError, Exp memory) {
/*
We are doing this as:
getExp(mulUInt(expScale, scalar), divisor.mantissa)
How it works:
Exp = a / b;
Scalar = s;
`s / (a / b)` = `b * s / a` and since for an Exp `a = mantissa, b = expScale`
*/
(MathError err0, uint numerator) = mulUInt(expScale, scalar);
if (err0 != MathError.NO_ERROR) {
return (err0, Exp({mantissa: 0}));
}
return getExp(numerator, divisor.mantissa);
}
/**
* @dev Divide a scalar by an Exp, then truncate to return an unsigned integer.
*/
function divScalarByExpTruncate(uint scalar, Exp memory divisor) pure internal returns (MathError, uint) {
(MathError err, Exp memory fraction) = divScalarByExp(scalar, divisor);
if (err != MathError.NO_ERROR) {
return (err, 0);
}
return (MathError.NO_ERROR, truncate(fraction));
}
/**
* @dev Multiplies two exponentials, returning a new exponential.
*/
function mulExp(Exp memory a, Exp memory b) pure internal returns (MathError, Exp memory) {
(MathError err0, uint doubleScaledProduct) = mulUInt(a.mantissa, b.mantissa);
if (err0 != MathError.NO_ERROR) {
return (err0, Exp({mantissa: 0}));
}
// We add half the scale before dividing so that we get rounding instead of truncation.
// See "Listing 6" and text above it at https://accu.org/index.php/journals/1717
// Without this change, a result like 6.6...e-19 will be truncated to 0 instead of being rounded to 1e-18.
(MathError err1, uint doubleScaledProductWithHalfScale) = addUInt(halfExpScale, doubleScaledProduct);
if (err1 != MathError.NO_ERROR) {
return (err1, Exp({mantissa: 0}));
}
(MathError err2, uint product) = divUInt(doubleScaledProductWithHalfScale, expScale);
// The only error `div` can return is MathError.DIVISION_BY_ZERO but we control `expScale` and it is not zero.
assert(err2 == MathError.NO_ERROR);
return (MathError.NO_ERROR, Exp({mantissa: product}));
}
/**
* @dev Multiplies two exponentials given their mantissas, returning a new exponential.
*/
function mulExp(uint a, uint b) pure internal returns (MathError, Exp memory) {
return mulExp(Exp({mantissa: a}), Exp({mantissa: b}));
}
/**
* @dev Multiplies three exponentials, returning a new exponential.
*/
function mulExp3(Exp memory a, Exp memory b, Exp memory c) pure internal returns (MathError, Exp memory) {
(MathError err, Exp memory ab) = mulExp(a, b);
if (err != MathError.NO_ERROR) {
return (err, ab);
}
return mulExp(ab, c);
}
/**
* @dev Divides two exponentials, returning a new exponential.
* (a/scale) / (b/scale) = (a/scale) * (scale/b) = a/b,
* which we can scale as an Exp by calling getExp(a.mantissa, b.mantissa)
*/
function divExp(Exp memory a, Exp memory b) pure internal returns (MathError, Exp memory) {
return getExp(a.mantissa, b.mantissa);
}
/**
* @dev Truncates the given exp to a whole number value.
* For example, truncate(Exp{mantissa: 15 * expScale}) = 15
*/
function truncate(Exp memory exp) pure internal returns (uint) {
// Note: We are not using careful math here as we're performing a division that cannot fail
return exp.mantissa / expScale;
}
/**
* @dev Checks if first Exp is less than second Exp.
*/
function lessThanExp(Exp memory left, Exp memory right) pure internal returns (bool) {
return left.mantissa < right.mantissa;
}
/**
* @dev Checks if left Exp <= right Exp.
*/
function lessThanOrEqualExp(Exp memory left, Exp memory right) pure internal returns (bool) {
return left.mantissa <= right.mantissa;
}
/**
* @dev Checks if left Exp > right Exp.
*/
function greaterThanExp(Exp memory left, Exp memory right) pure internal returns (bool) {
return left.mantissa > right.mantissa;
}
/**
* @dev returns true if Exp is exactly zero
*/
function isZeroExp(Exp memory value) pure internal returns (bool) {
return value.mantissa == 0;
}
function safe224(uint n, string memory errorMessage) pure internal returns (uint224) {
require(n < 2**224, errorMessage);
return uint224(n);
}
function safe32(uint n, string memory errorMessage) pure internal returns (uint32) {
require(n < 2**32, errorMessage);
return uint32(n);
}
function add_(Exp memory a, Exp memory b) pure internal returns (Exp memory) {
return Exp({mantissa: add_(a.mantissa, b.mantissa)});
}
function add_(Double memory a, Double memory b) pure internal returns (Double memory) {
return Double({mantissa: add_(a.mantissa, b.mantissa)});
}
function add_(uint a, uint b) pure internal returns (uint) {
return add_(a, b, "addition overflow");
}
function add_(uint a, uint b, string memory errorMessage) pure internal returns (uint) {
uint c = a + b;
require(c >= a, errorMessage);
return c;
}
function sub_(Exp memory a, Exp memory b) pure internal returns (Exp memory) {
return Exp({mantissa: sub_(a.mantissa, b.mantissa)});
}
function sub_(Double memory a, Double memory b) pure internal returns (Double memory) {
return Double({mantissa: sub_(a.mantissa, b.mantissa)});
}
function sub_(uint a, uint b) pure internal returns (uint) {
return sub_(a, b, "subtraction underflow");
}
function sub_(uint a, uint b, string memory errorMessage) pure internal returns (uint) {
require(b <= a, errorMessage);
return a - b;
}
function mul_(Exp memory a, Exp memory b) pure internal returns (Exp memory) {
return Exp({mantissa: mul_(a.mantissa, b.mantissa) / expScale});
}
function mul_(Exp memory a, uint b) pure internal returns (Exp memory) {
return Exp({mantissa: mul_(a.mantissa, b)});
}
function mul_(uint a, Exp memory b) pure internal returns (uint) {
return mul_(a, b.mantissa) / expScale;
}
function mul_(Double memory a, Double memory b) pure internal returns (Double memory) {
return Double({mantissa: mul_(a.mantissa, b.mantissa) / doubleScale});
}
function mul_(Double memory a, uint b) pure internal returns (Double memory) {
return Double({mantissa: mul_(a.mantissa, b)});
}
function mul_(uint a, Double memory b) pure internal returns (uint) {
return mul_(a, b.mantissa) / doubleScale;
}
function mul_(uint a, uint b) pure internal returns (uint) {
return mul_(a, b, "multiplication overflow");
}
function mul_(uint a, uint b, string memory errorMessage) pure internal returns (uint) {
if (a == 0 || b == 0) {
return 0;
}
uint c = a * b;
require(c / a == b, errorMessage);
return c;
}
function div_(Exp memory a, Exp memory b) pure internal returns (Exp memory) {
return Exp({mantissa: div_(mul_(a.mantissa, expScale), b.mantissa)});
}
function div_(Exp memory a, uint b) pure internal returns (Exp memory) {
return Exp({mantissa: div_(a.mantissa, b)});
}
function div_(uint a, Exp memory b) pure internal returns (uint) {
return div_(mul_(a, expScale), b.mantissa);
}
function div_(Double memory a, Double memory b) pure internal returns (Double memory) {
return Double({mantissa: div_(mul_(a.mantissa, doubleScale), b.mantissa)});
}
function div_(Double memory a, uint b) pure internal returns (Double memory) {
return Double({mantissa: div_(a.mantissa, b)});
}
function div_(uint a, Double memory b) pure internal returns (uint) {
return div_(mul_(a, doubleScale), b.mantissa);
}
function div_(uint a, uint b) pure internal returns (uint) {
return div_(a, b, "divide by zero");
}
function div_(uint a, uint b, string memory errorMessage) pure internal returns (uint) {
require(b > 0, errorMessage);
return a / b;
}
function fraction(uint a, uint b) pure internal returns (Double memory) {
return Double({mantissa: div_(mul_(a, doubleScale), b)});
}
}
// SPDX-License-Identifier: MIT
interface IVault is IERC20 {
function token() external view returns (address);
function claimInsurance() external; // NOTE: Only yDelegatedVault implements this
function getRatio() external view returns (uint256);
function deposit(uint256) external;
function withdraw(uint256) external;
function earn() external;
}
// SPDX-License-Identifier: MIT
interface IStakingRewards {
function balanceOf(address account) external view returns (uint256);
function earned(address account) external view returns (uint256);
function exit() external;
function getReward() external;
function getRewardForDuration() external view returns (uint256);
function lastTimeRewardApplicable() external view returns (uint256);
function lastUpdateTime() external view returns (uint256);
function notifyRewardAmount(uint256 reward) external;
function periodFinish() external view returns (uint256);
function rewardPerToken() external view returns (uint256);
function rewardPerTokenStored() external view returns (uint256);
function rewardRate() external view returns (uint256);
function rewards(address) external view returns (uint256);
function rewardsDistribution() external view returns (address);
function rewardsDuration() external view returns (uint256);
function rewardsToken() external view returns (address);
function stake(uint256 amount) external;
function stakeWithPermit(
uint256 amount,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function stakingToken() external view returns (address);
function totalSupply() external view returns (uint256);
function userRewardPerTokenPaid(address) external view returns (uint256);
function withdraw(uint256 amount) external;
}
interface IStakingRewardsFactory {
function deploy(address stakingToken, uint256 rewardAmount) external;
function isOwner() external view returns (bool);
function notifyRewardAmount(address stakingToken) external;
function notifyRewardAmounts() external;
function owner() external view returns (address);
function renounceOwnership() external;
function rewardsToken() external view returns (address);
function stakingRewardsGenesis() external view returns (uint256);
function stakingRewardsInfoByStakingToken(address)
external
view
returns (address stakingRewards, uint256 rewardAmount);
function stakingTokens(uint256) external view returns (address);
function transferOwnership(address newOwner) external;
}
// SPDX-License-Identifier: MIT
// SPDX-License-Identifier: MIT
interface UniswapRouterV2 {
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function addLiquidity(
address tokenA,
address tokenB,
uint256 amountADesired,
uint256 amountBDesired,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
)
external
returns (
uint256 amountA,
uint256 amountB,
uint256 liquidity
);
function addLiquidityETH(
address token,
uint256 amountTokenDesired,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline
)
external
payable
returns (
uint256 amountToken,
uint256 amountETH,
uint256 liquidity
);
function removeLiquidity(
address tokenA,
address tokenB,
uint256 liquidity,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
) external returns (uint256 amountA, uint256 amountB);
function getAmountsOut(uint256 amountIn, address[] calldata path)
external
view
returns (uint256[] memory amounts);
function getAmountsIn(uint256 amountOut, address[] calldata path)
external
view
returns (uint256[] memory amounts);
function swapETHForExactTokens(
uint256 amountOut,
address[] calldata path,
address to,
uint256 deadline
) external payable returns (uint256[] memory amounts);
function swapExactETHForTokens(
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external payable returns (uint256[] memory amounts);
}
interface IUniswapV2Pair {
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
event Transfer(address indexed from, address indexed to, uint256 value);
function name() external pure returns (string memory);
function symbol() external pure returns (string memory);
function decimals() external pure returns (uint8);
function totalSupply() external view returns (uint256);
function balanceOf(address owner) external view returns (uint256);
function allowance(address owner, address spender)
external
view
returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transfer(address to, uint256 value) external returns (bool);
function transferFrom(
address from,
address to,
uint256 value
) external returns (bool);
function DOMAIN_SEPARATOR() external view returns (bytes32);
function PERMIT_TYPEHASH() external pure returns (bytes32);
function nonces(address owner) external view returns (uint256);
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
event Mint(address indexed sender, uint256 amount0, uint256 amount1);
event Burn(
address indexed sender,
uint256 amount0,
uint256 amount1,
address indexed to
);
event Swap(
address indexed sender,
uint256 amount0In,
uint256 amount1In,
uint256 amount0Out,
uint256 amount1Out,
address indexed to
);
event Sync(uint112 reserve0, uint112 reserve1);
function MINIMUM_LIQUIDITY() external pure returns (uint256);
function factory() external view returns (address);
function token0() external view returns (address);
function token1() external view returns (address);
function getReserves()
external
view
returns (
uint112 reserve0,
uint112 reserve1,
uint32 blockTimestampLast
);
function price0CumulativeLast() external view returns (uint256);
function price1CumulativeLast() external view returns (uint256);
function kLast() external view returns (uint256);
function mint(address to) external returns (uint256 liquidity);
function burn(address to)
external
returns (uint256 amount0, uint256 amount1);
function swap(
uint256 amount0Out,
uint256 amount1Out,
address to,
bytes calldata data
) external;
function skim(address to) external;
function sync() external;
}
interface IUniswapV2Factory {
event PairCreated(
address indexed token0,
address indexed token1,
address pair,
uint256
);
function getPair(address tokenA, address tokenB)
external
view
returns (address pair);
function allPairs(uint256) external view returns (address pair);
function allPairsLength() external view returns (uint256);
function feeTo() external view returns (address);
function feeToSetter() external view returns (address);
function createPair(address tokenA, address tokenB)
external
returns (address pair);
}
// SPDX-License-Identifier: MIT
interface IController {
function vaults(address) external view returns (address);
function rewards() external view returns (address);
function devfund() external view returns (address);
function treasury() external view returns (address);
function balanceOf(address) external view returns (uint256);
function withdraw(address, uint256) external;
function earn(address, uint256) external;
}
// SPDX-License-Identifier: MIT
interface IMasterchef {
function BONUS_MULTIPLIER() external view returns (uint256);
function add(
uint256 _allocPoint,
address _lpToken,
bool _withUpdate
) external;
function bonusEndBlock() external view returns (uint256);
function deposit(uint256 _pid, uint256 _amount) external;
function dev(address _devaddr) external;
function devFundDivRate() external view returns (uint256);
function devaddr() external view returns (address);
function emergencyWithdraw(uint256 _pid) external;
function getMultiplier(uint256 _from, uint256 _to)
external
view
returns (uint256);
function massUpdatePools() external;
function owner() external view returns (address);
function pendingMM(uint256 _pid, address _user)
external
view
returns (uint256);
function mm() external view returns (address);
function mmPerBlock() external view returns (uint256);
function poolInfo(uint256)
external
view
returns (
address lpToken,
uint256 allocPoint,
uint256 lastRewardBlock,
uint256 accMMPerShare
);
function poolLength() external view returns (uint256);
function renounceOwnership() external;
function set(
uint256 _pid,
uint256 _allocPoint,
bool _withUpdate
) external;
function setBonusEndBlock(uint256 _bonusEndBlock) external;
function setDevFundDivRate(uint256 _devFundDivRate) external;
function setMMPerBlock(uint256 _mmPerBlock) external;
function startBlock() external view returns (uint256);
function totalAllocPoint() external view returns (uint256);
function transferOwnership(address newOwner) external;
function updatePool(uint256 _pid) external;
function userInfo(uint256, address)
external
view
returns (uint256 amount, uint256 rewardDebt);
function withdraw(uint256 _pid, uint256 _amount) external;
function notifyBuybackReward(uint256 _amount) external;
}
// Strategy Contract Basics
abstract contract StrategyBase {
using SafeERC20 for IERC20;
using Address for address;
using SafeMath for uint256;
// Perfomance fee 30% to buyback
uint256 public performanceFee = 30000;
uint256 public constant performanceMax = 100000;
// Withdrawal fee 0.2% to buyback
// - 0.14% to treasury
// - 0.06% to dev fund
uint256 public treasuryFee = 140;
uint256 public constant treasuryMax = 100000;
uint256 public devFundFee = 60;
uint256 public constant devFundMax = 100000;
// buyback ready
bool public buybackEnabled = false;
address public mmToken;
address public masterChef;
// Tokens
address public want;
address public constant weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
// buyback coins
address public constant usdcBuyback = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
address public wbtcBuyback = 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599;
address public renbtcBuyback = 0xEB4C2781e4ebA804CE9a9803C67d0893436bB27D;
// User accounts
address public governance;
address public controller;
address public strategist;
address public timelock;
// Dex
address public univ2Router2 = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
constructor(
address _want,
address _governance,
address _strategist,
address _controller,
address _timelock
) public {
require(_want != address(0));
require(_governance != address(0));
require(_strategist != address(0));
require(_controller != address(0));
require(_timelock != address(0));
want = _want;
governance = _governance;
strategist = _strategist;
controller = _controller;
timelock = _timelock;
}
// **** Modifiers **** //
modifier onlyBenevolent {
require(
msg.sender == tx.origin ||
msg.sender == governance ||
msg.sender == strategist
);
_;
}
// **** Views **** //
function balanceOfWant() public view returns (uint256) {
return IERC20(want).balanceOf(address(this));
}
function balanceOfPool() public virtual view returns (uint256);
function balanceOf() public view returns (uint256) {
return balanceOfWant().add(balanceOfPool());
}
function getName() external virtual pure returns (string memory);
// **** Setters **** //
function setDevFundFee(uint256 _devFundFee) external {
require(msg.sender == timelock, "!timelock");
devFundFee = _devFundFee;
}
function setTreasuryFee(uint256 _treasuryFee) external {
require(msg.sender == timelock, "!timelock");
treasuryFee = _treasuryFee;
}
function setPerformanceFee(uint256 _performanceFee) external {
require(msg.sender == timelock, "!timelock");
performanceFee = _performanceFee;
}
function setStrategist(address _strategist) external {
require(msg.sender == governance, "!governance");
strategist = _strategist;
}
function setGovernance(address _governance) external {
require(msg.sender == governance, "!governance");
governance = _governance;
}
function setTimelock(address _timelock) external {
require(msg.sender == timelock, "!timelock");
timelock = _timelock;
}
function setController(address _controller) external {
require(msg.sender == timelock, "!timelock");
controller = _controller;
}
function setMmToken(address _mmToken) external {
require(msg.sender == governance, "!governance");
mmToken = _mmToken;
}
function setBuybackEnabled(bool _buybackEnabled) external {
require(msg.sender == governance, "!governance");
buybackEnabled = _buybackEnabled;
}
function setMasterChef(address _masterChef) external {
require(msg.sender == governance, "!governance");
masterChef = _masterChef;
}
// **** State mutations **** //
function deposit() public virtual;
function withdraw(IERC20 _asset) external virtual returns (uint256 balance);
// Controller only function for creating additional rewards from dust
function _withdrawNonWantAsset(IERC20 _asset) internal returns (uint256 balance) {
require(msg.sender == controller, "!controller");
require(want != address(_asset), "want");
balance = _asset.balanceOf(address(this));
_asset.safeTransfer(controller, balance);
}
// Withdraw partial funds, normally used with a vault withdrawal
function withdraw(uint256 _amount) external {
require(msg.sender == controller, "!controller");
uint256 _balance = IERC20(want).balanceOf(address(this));
if (_balance < _amount) {
_amount = _withdrawSome(_amount.sub(_balance));
_amount = _amount.add(_balance);
}
uint256 _feeDev = _amount.mul(devFundFee).div(devFundMax);
uint256 _feeTreasury = _amount.mul(treasuryFee).div(treasuryMax);
if (buybackEnabled == true) {
// we want buyback mm using LP token
(address _buybackPrinciple, uint256 _buybackAmount) = _convertWantToBuyback(_feeDev.add(_feeTreasury));
buybackAndNotify(_buybackPrinciple, _buybackAmount);
} else {
IERC20(want).safeTransfer(IController(controller).devfund(), _feeDev);
IERC20(want).safeTransfer(IController(controller).treasury(), _feeTreasury);
}
address _vault = IController(controller).vaults(address(want));
require(_vault != address(0), "!vault"); // additional protection so we don't burn the funds
IERC20(want).safeTransfer(_vault, _amount.sub(_feeDev).sub(_feeTreasury));
}
// buyback MM and notify MasterChef
function buybackAndNotify(address _buybackPrinciple, uint256 _buybackAmount) internal {
if (buybackEnabled == true) {
_swapUniswap(_buybackPrinciple, mmToken, _buybackAmount);
uint256 _mmBought = IERC20(mmToken).balanceOf(address(this));
IERC20(mmToken).safeTransfer(masterChef, _mmBought);
IMasterchef(masterChef).notifyBuybackReward(_mmBought);
}
}
// Withdraw all funds, normally used when migrating strategies
function withdrawAll() external returns (uint256 balance) {
require(msg.sender == controller, "!controller");
_withdrawAll();
balance = IERC20(want).balanceOf(address(this));
address _vault = IController(controller).vaults(address(want));
require(_vault != address(0), "!vault"); // additional protection so we don't burn the funds
IERC20(want).safeTransfer(_vault, balance);
}
function _withdrawAll() internal {
_withdrawSome(balanceOfPool());
}
function _withdrawSome(uint256 _amount) internal virtual returns (uint256);
// convert LP to buyback principle token
function _convertWantToBuyback(uint256 _lpAmount) internal virtual returns (address, uint256);
function harvest() public virtual;
// **** Emergency functions ****
function execute(address _target, bytes memory _data)
public
payable
returns (bytes memory response)
{
require(msg.sender == timelock, "!timelock");
require(_target != address(0), "!target");
// call contract in current context
assembly {
let succeeded := delegatecall(
sub(gas(), 5000),
_target,
add(_data, 0x20),
mload(_data),
0,
0
)
let size := returndatasize()
response := mload(0x40)
mstore(
0x40,
add(response, and(add(add(size, 0x20), 0x1f), not(0x1f)))
)
mstore(response, size)
returndatacopy(add(response, 0x20), 0, size)
switch iszero(succeeded)
case 1 {
// throw if delegatecall failed
revert(add(response, 0x20), size)
}
}
}
// **** Internal functions ****
function _swapUniswap(
address _from,
address _to,
uint256 _amount
) internal {
require(_to != address(0));
// Swap with uniswap
IERC20(_from).safeApprove(univ2Router2, 0);
IERC20(_from).safeApprove(univ2Router2, _amount);
address[] memory path;
if (_to == mmToken && buybackEnabled == true) {
if (_from == usdcBuyback){
path = new address[](2);
path[0] = _from;
path[1] = _to;
}else if(_from == renbtcBuyback || _from == wbtcBuyback){
path = new address[](4);
path[0] = _from;
path[1] = weth;
path[2] = usdcBuyback;
path[3] = _to;
}else{
path = new address[](3);
path[0] = _from;
path[1] = usdcBuyback;
path[2] = _to;
}
} else{
if (_from == weth || _to == weth) {
path = new address[](2);
path[0] = _from;
path[1] = _to;
} else {
path = new address[](3);
path[0] = _from;
path[1] = weth;
path[2] = _to;
}
}
UniswapRouterV2(univ2Router2).swapExactTokensForTokens(
_amount,
0,
path,
address(this),
now.add(60)
);
}
}
// SPDX-License-Identifier: MIT
interface ICToken {
function totalSupply() external view returns (uint256);
function totalBorrows() external returns (uint256);
function borrowIndex() external returns (uint256);
function repayBorrow(uint256 repayAmount) external returns (uint256);
function redeemUnderlying(uint256 redeemAmount) external returns (uint256);
function borrow(uint256 borrowAmount) external returns (uint256);
function mint(uint256 mintAmount) external returns (uint256);
function transfer(address dst, uint256 amount) external returns (bool);
function transferFrom(
address src,
address dst,
uint256 amount
) external returns (bool);
function approve(address spender, uint256 amount) external returns (bool);
function allowance(address owner, address spender)
external
view
returns (uint256);
function balanceOf(address owner) external view returns (uint256);
function balanceOfUnderlying(address owner) external returns (uint256);
function getAccountSnapshot(address account)
external
view
returns (
uint256,
uint256,
uint256,
uint256
);
function borrowRatePerBlock() external view returns (uint256);
function supplyRatePerBlock() external view returns (uint256);
function totalBorrowsCurrent() external returns (uint256);
function borrowBalanceCurrent(address account) external returns (uint256);
function borrowBalanceStored(address account)
external
view
returns (uint256);
function exchangeRateCurrent() external returns (uint256);
function exchangeRateStored() external view returns (uint256);
function getCash() external view returns (uint256);
function accrueInterest() external returns (uint256);
function seize(
address liquidator,
address borrower,
uint256 seizeTokens
) external returns (uint256);
}
interface ICEther {
function mint() external payable;
/**
* @notice Sender redeems cTokens in exchange for the underlying asset
* @dev Accrues interest whether or not the operation succeeds, unless reverted
* @param redeemTokens The number of cTokens to redeem into underlying
* @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)
*/
function redeem(uint256 redeemTokens) external returns (uint256);
/**
* @notice Sender redeems cTokens in exchange for a specified amount of underlying asset
* @dev Accrues interest whether or not the operation succeeds, unless reverted
* @param redeemAmount The amount of underlying to redeem
* @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)
*/
function redeemUnderlying(uint256 redeemAmount) external returns (uint256);
/**
* @notice Sender borrows assets from the protocol to their own address
* @param borrowAmount The amount of the underlying asset to borrow
* @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)
*/
function borrow(uint256 borrowAmount) external returns (uint256);
/**
* @notice Sender repays their own borrow
* @dev Reverts upon any failure
*/
function repayBorrow() external payable;
/**
* @notice Sender repays a borrow belonging to borrower
* @dev Reverts upon any failure
* @param borrower the account with the debt being payed off
*/
function repayBorrowBehalf(address borrower) external payable;
/**
* @notice The sender liquidates the borrowers collateral.
* The collateral seized is transferred to the liquidator.
* @dev Reverts upon any failure
* @param borrower The borrower of this cToken to be liquidated
* @param cTokenCollateral The market in which to seize collateral from the borrower
*/
function liquidateBorrow(address borrower, address cTokenCollateral)
external
payable;
}
interface IComptroller {
function compAccrued(address) external view returns (uint256);
function compSupplierIndex(address, address)
external
view
returns (uint256);
function compBorrowerIndex(address, address)
external
view
returns (uint256);
function compSpeeds(address) external view returns (uint256);
function compBorrowState(address) external view returns (uint224, uint32);
function compSupplyState(address) external view returns (uint224, uint32);
/*** Assets You Are In ***/
function enterMarkets(address[] calldata cTokens)
external
returns (uint256[] memory);
function exitMarket(address cToken) external returns (uint256);
/*** Policy Hooks ***/
function mintAllowed(
address cToken,
address minter,
uint256 mintAmount
) external returns (uint256);
function mintVerify(
address cToken,
address minter,
uint256 mintAmount,
uint256 mintTokens
) external;
function redeemAllowed(
address cToken,
address redeemer,
uint256 redeemTokens
) external returns (uint256);
function redeemVerify(
address cToken,
address redeemer,
uint256 redeemAmount,
uint256 redeemTokens
) external;
function borrowAllowed(
address cToken,
address borrower,
uint256 borrowAmount
) external returns (uint256);
function borrowVerify(
address cToken,
address borrower,
uint256 borrowAmount
) external;
function repayBorrowAllowed(
address cToken,
address payer,
address borrower,
uint256 repayAmount
) external returns (uint256);
function repayBorrowVerify(
address cToken,
address payer,
address borrower,
uint256 repayAmount,
uint256 borrowerIndex
) external;
function liquidateBorrowAllowed(
address cTokenBorrowed,
address cTokenCollateral,
address liquidator,
address borrower,
uint256 repayAmount
) external returns (uint256);
function liquidateBorrowVerify(
address cTokenBorrowed,
address cTokenCollateral,
address liquidator,
address borrower,
uint256 repayAmount,
uint256 seizeTokens
) external;
function seizeAllowed(
address cTokenCollateral,
address cTokenBorrowed,
address liquidator,
address borrower,
uint256 seizeTokens
) external returns (uint256);
function seizeVerify(
address cTokenCollateral,
address cTokenBorrowed,
address liquidator,
address borrower,
uint256 seizeTokens
) external;
function transferAllowed(
address cToken,
address src,
address dst,
uint256 transferTokens
) external returns (uint256);
function transferVerify(
address cToken,
address src,
address dst,
uint256 transferTokens
) external;
/*** Liquidity/Liquidation Calculations ***/
function liquidateCalculateSeizeTokens(
address cTokenBorrowed,
address cTokenCollateral,
uint256 repayAmount
) external view returns (uint256, uint256);
// Claim all the COMP accrued by holder in all markets
function claimComp(address holder) external;
// Claim all the COMP accrued by holder in specific markets
function claimComp(address holder, address[] calldata cTokens) external;
// Claim all the COMP accrued by specific holders in specific markets for their supplies and/or borrows
function claimComp(
address[] calldata holders,
address[] calldata cTokens,
bool borrowers,
bool suppliers
) external;
function markets(address cTokenAddress)
external
view
returns (bool, uint256);
}
interface ICompoundLens {
function getCompBalanceMetadataExt(
address comp,
address comptroller,
address account
)
external
returns (
uint256 balance,
uint256 votes,
address delegate,
uint256 allocated
);
}
// SPDX-License-Identifier: MIT
contract StrategyCmpdUsdcV1 is StrategyBase, Exponential {
address
public constant comptroller = 0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B;
address public constant lens = 0xd513d22422a3062Bd342Ae374b4b9c20E0a9a074;
address public constant usdc = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
address public constant comp = 0xc00e94Cb662C3520282E6f5717214004A7f26888;
address public constant cusdc = 0x39AA39c021dfbaE8faC545936693aC917d5E7563;
address public constant cether = 0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5;
// Require a 0.1 buffer between
// market collateral factor and strategy's collateral factor
// when leveraging
uint256 colFactorLeverageBuffer = 100;
uint256 colFactorLeverageBufferMax = 1000;
// Allow a 0.05 buffer
// between market collateral factor and strategy's collateral factor
// until we have to deleverage
// This is so we can hit max leverage and keep accruing interest
uint256 colFactorSyncBuffer = 50;
uint256 colFactorSyncBufferMax = 1000;
// Keeper bots
// Maintain leverage within buffer
mapping(address => bool) keepers;
constructor(
address _governance,
address _strategist,
address _controller,
address _timelock
)
public
StrategyBase(usdc, _governance, _strategist, _controller, _timelock)
{
// Enter cUSDC Market
address[] memory ctokens = new address[](1);
ctokens[0] = cusdc;
IComptroller(comptroller).enterMarkets(ctokens);
}
// **** Modifiers **** //
modifier onlyKeepers {
require(
keepers[msg.sender] ||
msg.sender == address(this) ||
msg.sender == strategist ||
msg.sender == governance,
"!keepers"
);
_;
}
// **** Views **** //
function getName() external override pure returns (string memory) {
return "StrategyCmpdUsdcV1";
}
function getSuppliedView() public view returns (uint256) {
(, uint256 cTokenBal, , uint256 exchangeRate) = ICToken(cusdc)
.getAccountSnapshot(address(this));
(, uint256 bal) = mulScalarTruncate(
Exp({mantissa: exchangeRate}),
cTokenBal
);
return bal;
}
function getBorrowedView() public view returns (uint256) {
return ICToken(cusdc).borrowBalanceStored(address(this));
}
function balanceOfPool() public override view returns (uint256) {
uint256 supplied = getSuppliedView();
uint256 borrowed = getBorrowedView();
return supplied.sub(borrowed);
}
// Given an unleveraged supply balance, return the target
// leveraged supply balance which is still within the safety buffer
function getLeveragedSupplyTarget(uint256 supplyBalance)
public
view
returns (uint256)
{
uint256 leverage = getMaxLeverage();
return supplyBalance.mul(leverage).div(1e18);
}
function getSafeLeverageColFactor() public view returns (uint256) {
uint256 colFactor = getMarketColFactor();
// Collateral factor within the buffer
uint256 safeColFactor = colFactor.sub(
colFactorLeverageBuffer.mul(1e18).div(colFactorLeverageBufferMax)
);
return safeColFactor;
}
function getSafeSyncColFactor() public view returns (uint256) {
uint256 colFactor = getMarketColFactor();
// Collateral factor within the buffer
uint256 safeColFactor = colFactor.sub(
colFactorSyncBuffer.mul(1e18).div(colFactorSyncBufferMax)
);
return safeColFactor;
}
function getMarketColFactor() public view returns (uint256) {
(, uint256 colFactor) = IComptroller(comptroller).markets(cusdc);
return colFactor;
}
// Max leverage we can go up to, w.r.t safe buffer
function getMaxLeverage() public view returns (uint256) {
uint256 safeLeverageColFactor = getSafeLeverageColFactor();
// Infinite geometric series
uint256 leverage = uint256(1e36).div(1e18 - safeLeverageColFactor);
return leverage;
}
// If we have a strategy position at this SOS borrow rate and left unmonitored for 24+ hours, we might get liquidated
// To safeguard with enough buffer, we divide the borrow rate by 2 which indicates allowing 48 hours response time
function getSOSBorrowRate() public view returns (uint256) {
uint256 safeColFactor = getSafeLeverageColFactor();
return (colFactorLeverageBuffer.mul(182).mul(1e20).div(colFactorLeverageBufferMax)).div(safeColFactor);
}
// **** Pseudo-view functions (use `callStatic` on these) **** //
/* The reason why these exists is because of the nature of the
interest accruing supply + borrow balance. The "view" methods
are technically snapshots and don't represent the real value.
As such there are pseudo view methods where you can retrieve the
results by calling `callStatic`.
*/
function getCompAccrued() public returns (uint256) {
(, , , uint256 accrued) = ICompoundLens(lens).getCompBalanceMetadataExt(
comp,
comptroller,
address(this)
);
return accrued;
}
function getColFactor() public returns (uint256) {
uint256 supplied = getSupplied();
uint256 borrowed = getBorrowed();
return borrowed.mul(1e18).div(supplied);
}
function getSuppliedUnleveraged() public returns (uint256) {
uint256 supplied = getSupplied();
uint256 borrowed = getBorrowed();
return supplied.sub(borrowed);
}
function getSupplied() public returns (uint256) {
return ICToken(cusdc).balanceOfUnderlying(address(this));
}
function getBorrowed() public returns (uint256) {
return ICToken(cusdc).borrowBalanceCurrent(address(this));
}
function getBorrowable() public returns (uint256) {
uint256 supplied = getSupplied();
uint256 borrowed = getBorrowed();
(, uint256 colFactor) = IComptroller(comptroller).markets(cusdc);
// 99.99% just in case some dust accumulates
return
supplied.mul(colFactor).div(1e18).sub(borrowed).mul(9999).div(
10000
);
}
function getCurrentLeverage() public returns (uint256) {
uint256 supplied = getSupplied();
uint256 borrowed = getBorrowed();
return supplied.mul(1e18).div(supplied.sub(borrowed));
}
// **** Setters **** //
function addKeeper(address _keeper) public {
require(
msg.sender == governance || msg.sender == strategist,
"!governance"
);
keepers[_keeper] = true;
}
function removeKeeper(address _keeper) public {
require(
msg.sender == governance || msg.sender == strategist,
"!governance"
);
keepers[_keeper] = false;
}
function setColFactorLeverageBuffer(uint256 _colFactorLeverageBuffer)
public
{
require(
msg.sender == governance || msg.sender == strategist,
"!governance"
);
colFactorLeverageBuffer = _colFactorLeverageBuffer;
}
function setColFactorSyncBuffer(uint256 _colFactorSyncBuffer) public {
require(
msg.sender == governance || msg.sender == strategist,
"!governance"
);
colFactorSyncBuffer = _colFactorSyncBuffer;
}
// **** State mutations **** //
// Do a `callStatic` on this.
// If it returns true then run it for realz. (i.e. eth_signedTx, not eth_call)
function sync() public returns (bool) {
uint256 colFactor = getColFactor();
uint256 safeSyncColFactor = getSafeSyncColFactor();
// If we're not safe
if (colFactor > safeSyncColFactor) {
uint256 unleveragedSupply = getSuppliedUnleveraged();
uint256 idealSupply = getLeveragedSupplyTarget(unleveragedSupply);
deleverageUntil(idealSupply);
return true;
}
return false;
}
function leverageToMax() public {
uint256 unleveragedSupply = getSuppliedUnleveraged();
uint256 idealSupply = getLeveragedSupplyTarget(unleveragedSupply);
leverageUntil(idealSupply);
}
// Leverages until we're supplying <x> amount
// 1. Redeem <x> USDC
// 2. Repay <x> USDC
function leverageUntil(uint256 _supplyAmount) public onlyKeepers {
// 1. Borrow out <X> USDC
// 2. Supply <X> USDC
uint256 leverage = getMaxLeverage();
uint256 unleveragedSupply = getSuppliedUnleveraged();
require(
_supplyAmount >= unleveragedSupply &&
_supplyAmount <= unleveragedSupply.mul(leverage).div(1e18),
"!leverage"
);
// Since we're only leveraging one asset
// Supplied = borrowed
uint256 _borrowAndSupply;
uint256 supplied = getSupplied();
while (supplied < _supplyAmount) {
_borrowAndSupply = getBorrowable();
if (supplied.add(_borrowAndSupply) > _supplyAmount) {
_borrowAndSupply = _supplyAmount.sub(supplied);
}
ICToken(cusdc).borrow(_borrowAndSupply);
deposit();
supplied = supplied.add(_borrowAndSupply);
}
}
function deleverageToMin() public {
uint256 unleveragedSupply = getSuppliedUnleveraged();
deleverageUntil(unleveragedSupply);
}
// Deleverages until we're supplying <x> amount
// 1. Redeem <x> USDC
// 2. Repay <x> USDC
function deleverageUntil(uint256 _supplyAmount) public onlyKeepers {
uint256 unleveragedSupply = getSuppliedUnleveraged();
uint256 supplied = getSupplied();
require(
_supplyAmount >= unleveragedSupply && _supplyAmount <= supplied,
"!deleverage"
);
// Since we're only leveraging on 1 asset
// redeemable = borrowable
uint256 _redeemAndRepay = getBorrowable();
do {
if (supplied.sub(_redeemAndRepay) < _supplyAmount) {
_redeemAndRepay = supplied.sub(_supplyAmount);
}
require(
ICToken(cusdc).redeemUnderlying(_redeemAndRepay) == 0,
"!redeem"
);
IERC20(usdc).safeApprove(cusdc, 0);
IERC20(usdc).safeApprove(cusdc, _redeemAndRepay);
require(ICToken(cusdc).repayBorrow(_redeemAndRepay) == 0, "!repay");
supplied = supplied.sub(_redeemAndRepay);
} while (supplied > _supplyAmount);
}
function _convertWantToBuyback(uint256 _lpAmount) internal override returns (address, uint256){
return (usdc, _lpAmount);
}
function harvest() public override onlyBenevolent {
address[] memory ctokens = new address[](1);
ctokens[0] = cusdc;
IComptroller(comptroller).claimComp(address(this), ctokens);
uint256 _comp = IERC20(comp).balanceOf(address(this));
if (_comp > 0) {
_swapUniswap(comp, want, _comp);
}
uint256 _want = IERC20(want).balanceOf(address(this));
uint256 _buybackAmount = _want.mul(performanceFee).div(performanceMax);
if (buybackEnabled == true && _buybackAmount > 0) {
buybackAndNotify(want, _buybackAmount);
} else {
// We want to get back Usdc
if (_want > 0) {
// Performance Fees goes to treasury
IERC20(want).safeTransfer(IController(controller).treasury(), _want.mul(performanceFee).div(performanceMax));
}
}
// re-invest to compounding profit
if (_want > 0) {
deposit();
}
}
function deposit() public override {
uint256 _want = IERC20(want).balanceOf(address(this));
if (_want > 0) {
IERC20(want).safeApprove(cusdc, 0);
IERC20(want).safeApprove(cusdc, _want);
require(ICToken(cusdc).mint(_want) == 0, "!deposit");
}
}
function _withdrawSome(uint256 _amount)
internal
override
returns (uint256)
{
// -- CoinFabrik: save initial balance --
uint256 _balance = balanceOfWant();
uint256 _redeem = _amount;
// Make sure market can cover liquidity
require(ICToken(cusdc).getCash() >= _redeem, "!cash-liquidity");
// How much borrowed amount do we need to free?
uint256 borrowed = getBorrowed();
uint256 supplied = getSupplied();
uint256 curLeverage = getCurrentLeverage();
uint256 borrowedToBeFree = _redeem.mul(curLeverage).div(1e18);
// If the amount we need to free is > borrowed
// Just free up all the borrowed amount
if (borrowedToBeFree > borrowed) {
this.deleverageToMin();
} else {
// Otherwise just keep freeing up borrowed amounts until
// we hit a safe number to redeem our underlying
this.deleverageUntil(supplied.sub(borrowedToBeFree));
}
// Redeems underlying
require(ICToken(cusdc).redeemUnderlying(_redeem) == 0, "!redeem");
// -- CoinFabrik: calculate tokens redeemed --
uint256 _reedemed = balanceOfWant();
_reedemed = _reedemed.sub(_balance);
return _reedemed;
}
// Controller only function for creating additional rewards from dust
function withdraw(IERC20 _asset) external override returns (uint256 balance) {
require(cusdc != address(_asset), "!cToken");
balance = _withdrawNonWantAsset(_asset);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_governance","type":"address"},{"internalType":"address","name":"_strategist","type":"address"},{"internalType":"address","name":"_controller","type":"address"},{"internalType":"address","name":"_timelock","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"_keeper","type":"address"}],"name":"addKeeper","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":"buybackEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cether","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"comp","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"comptroller","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cusdc","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deleverageToMin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_supplyAmount","type":"uint256"}],"name":"deleverageUntil","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"devFundFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"devFundMax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_target","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"execute","outputs":[{"internalType":"bytes","name":"response","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"getBorrowable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getBorrowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getBorrowedView","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getColFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getCompAccrued","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getCurrentLeverage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"supplyBalance","type":"uint256"}],"name":"getLeveragedSupplyTarget","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMarketColFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxLeverage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getName","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getSOSBorrowRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSafeLeverageColFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSafeSyncColFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSupplied","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getSuppliedUnleveraged","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getSuppliedView","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"harvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"leverageToMax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_supplyAmount","type":"uint256"}],"name":"leverageUntil","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"masterChef","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mmToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"performanceFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"performanceMax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_keeper","type":"address"}],"name":"removeKeeper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renbtcBuyback","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_buybackEnabled","type":"bool"}],"name":"setBuybackEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_colFactorLeverageBuffer","type":"uint256"}],"name":"setColFactorLeverageBuffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_colFactorSyncBuffer","type":"uint256"}],"name":"setColFactorSyncBuffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_controller","type":"address"}],"name":"setController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_devFundFee","type":"uint256"}],"name":"setDevFundFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_governance","type":"address"}],"name":"setGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_masterChef","type":"address"}],"name":"setMasterChef","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_mmToken","type":"address"}],"name":"setMmToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_performanceFee","type":"uint256"}],"name":"setPerformanceFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategist","type":"address"}],"name":"setStrategist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_timelock","type":"address"}],"name":"setTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_treasuryFee","type":"uint256"}],"name":"setTreasuryFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"strategist","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sync","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"timelock","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasuryFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasuryMax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"univ2Router2","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdc","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdcBuyback","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"want","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wbtcBuyback","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weth","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":[{"internalType":"contract IERC20","name":"_asset","type":"address"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
6080604052617530600055608c600155603c6002556003805460ff19169055600680546001600160a01b0319908116732260fac5e5542a773aa44fbcfedf7c193bc2c5991790915560078054821673eb4c2781e4eba804ce9a9803c67d0893436bb27d179055600c8054909116737a250d5630b4cf539739df2c5dacb4c659f2488d1790556064600d556103e8600e8190556032600f55601055348015620000a657600080fd5b506040516200427c3803806200427c83398181016040526080811015620000cc57600080fd5b508051602082015160408301516060909301519192909173a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48848484846001600160a01b0384166200011057600080fd5b6001600160a01b0383166200012457600080fd5b6001600160a01b0382166200013857600080fd5b6001600160a01b0381166200014c57600080fd5b600580546001600160a01b03199081166001600160a01b039788161790915560088054821695871695909517909455600a8054851693861693909317909255600980548416918516919091179055600b80549092169216919091179055604080516001808252818301909252606091602080830190803683370190505090507339aa39c021dfbae8fac545936693ac917d5e756381600081518110620001ee57fe5b6001600160a01b03909216602092830291909101820152604051631853304760e31b815260048101828152835160248301528351733d9819210a31b4961b30ef54be2aed79b9c9cd3b9363c2998238938693928392604490920191858101910280838360005b838110156200026e57818101518382015260200162000254565b5050505090500192505050600060405180830381600087803b1580156200029457600080fd5b505af1158015620002a9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015620002d357600080fd5b8101908080516040519392919084640100000000821115620002f457600080fd5b9083019060208201858111156200030a57600080fd5b82518660208202830111640100000000821117156200032857600080fd5b82525081516020918201928201910280838360005b83811015620003575781810151838201526020016200033d565b50505050905001604052505050505050505050613f02806200037a6000396000f3fe6080604052600436106103fa5760003560e01c80635fe3b56711610213578063a890dd9011610123578063cc32d176116100ab578063eb514af91161007a578063eb514af914610c12578063f4aa3a8d14610c3c578063f53f135014610c66578063f77c479114610c7b578063fff6cae914610c90576103fa565b8063cc32d17614610bbe578063ce7079ba14610bd3578063d0e30db014610be8578063d33219b414610bfd576103fa565b8063b635b8ae116100f2578063b635b8ae14610b19578063b9e3748914610b2e578063bdacb30314610b43578063c1a3d44c14610b76578063c7b9d53014610b8b576103fa565b8063a890dd9014610aa7578063ab033ea914610abc578063ac41ceb314610aef578063b01db4ec14610b04576103fa565b8063853828b6116101a65780639a9b567d116101755780639a9b567d146109f45780639c4b816314610a205780639eb52f6114610a35578063a1e003e414610a4a578063a2d9f4dc14610a74576103fa565b8063853828b614610997578063857a52b81461077857806387788782146109ac57806392eefe9b146109c1576103fa565b806377da835a116101e257806377da835a1461094357806377e741c7146109585780637cc79113146104b65780638081e1cf14610982576103fa565b80635fe3b567146108da57806370897b23146108ef578063722713f7146109195780637396a6261461092e576103fa565b80632bfc9c231161030e5780634641257d116102a157806359bca6791161027057806359bca6791461085c5780635aa6e675146108865780635bfb92ce1461089b5780635c208490146108b05780635eefb092146108c5576103fa565b80634641257d146107ea5780634a183ffc146107ff57806351cff8d914610814578063575a86b214610847576103fa565b80633e413bee116102dd5780633e413bee146107785780633fc8cef31461078d5780634032b72b146107a2578063463289ed146107d5576103fa565b80632bfc9c23146106fa5780632e1a7d4d1461070f578063302ab80d146107395780633c5dae9414610763576103fa565b806314e6ac09116103915780631cff79cd116103605780631cff79cd146105f05780631f1fcd51146106a65780631fe4a686146106bb57806320852ee7146106d05780632a99417d146106e5576103fa565b806314e6ac09146104fe57806315ac03fd14610528578063160d0da51461053d57806317d7de7c14610566576103fa565b806311588086116103cd57806311588086146104a157806313bd4b95146104b657806314a1fe02146104b657806314ae9f2e146104cb576103fa565b806305166eff146103ff5780630ea8b3bf14610434578063109d0af81461045b578063112666b71461048c575b600080fd5b34801561040b57600080fd5b506104326004803603602081101561042257600080fd5b50356001600160a01b0316610ca5565b005b34801561044057600080fd5b50610449610d1a565b60408051918252519081900360200190f35b34801561046757600080fd5b50610470610d5b565b604080516001600160a01b039092168252519081900360200190f35b34801561049857600080fd5b50610470610d73565b3480156104ad57600080fd5b50610449610d8b565b3480156104c257600080fd5b50610449610db4565b3480156104d757600080fd5b50610432600480360360208110156104ee57600080fd5b50356001600160a01b0316610dbb565b34801561050a57600080fd5b506104326004803603602081101561052157600080fd5b5035610e3e565b34801561053457600080fd5b50610470610e8e565b34801561054957600080fd5b50610552610ea6565b604080519115158252519081900360200190f35b34801561057257600080fd5b5061057b610eaf565b6040805160208082528351818301528351919283929083019185019080838360005b838110156105b557818101518382015260200161059d565b50505050905090810190601f1680156105e25780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61057b6004803603604081101561060657600080fd5b6001600160a01b03823516919081019060408101602082013564010000000081111561063157600080fd5b82018360208201111561064357600080fd5b8035906020019184600183028401116401000000008311171561066557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610edb945050505050565b3480156106b257600080fd5b50610470610fbe565b3480156106c757600080fd5b50610470610fcd565b3480156106dc57600080fd5b50610470610fdc565b3480156106f157600080fd5b50610449610fee565b34801561070657600080fd5b5061044961102f565b34801561071b57600080fd5b506104326004803603602081101561073257600080fd5b503561107b565b34801561074557600080fd5b506104326004803603602081101561075c57600080fd5b5035611417565b34801561076f57600080fd5b5061044961147e565b34801561078457600080fd5b506104706114c0565b34801561079957600080fd5b506104706114d8565b3480156107ae57600080fd5b50610432600480360360208110156107c557600080fd5b50356001600160a01b03166114f0565b3480156107e157600080fd5b50610449611576565b3480156107f657600080fd5b5061043261160d565b34801561080b57600080fd5b50610470611976565b34801561082057600080fd5b506104496004803603602081101561083757600080fd5b50356001600160a01b0316611985565b34801561085357600080fd5b506104706119ec565b34801561086857600080fd5b506104326004803603602081101561087f57600080fd5b50356119fb565b34801561089257600080fd5b50610470611a62565b3480156108a757600080fd5b50610449611a71565b3480156108bc57600080fd5b50610449611ab5565b3480156108d157600080fd5b50610449611b36565b3480156108e657600080fd5b50610470611b99565b3480156108fb57600080fd5b506104326004803603602081101561091257600080fd5b5035611bb1565b34801561092557600080fd5b50610449611c01565b34801561093a57600080fd5b50610449611c27565b34801561094f57600080fd5b50610449611c5c565b34801561096457600080fd5b506104326004803603602081101561097b57600080fd5b5035611d0e565b34801561098e57600080fd5b50610449611d5e565b3480156109a357600080fd5b50610449611dae565b3480156109b857600080fd5b50610449611f66565b3480156109cd57600080fd5b50610432600480360360208110156109e457600080fd5b50356001600160a01b0316611f6c565b348015610a0057600080fd5b5061043260048036036020811015610a1757600080fd5b50351515611fd9565b348015610a2c57600080fd5b50610449612039565b348015610a4157600080fd5b50610449612050565b348015610a5657600080fd5b5061044960048036036020811015610a6d57600080fd5b503561212b565b348015610a8057600080fd5b5061043260048036036020811015610a9757600080fd5b50356001600160a01b031661215d565b348015610ab357600080fd5b506104706121cc565b348015610ac857600080fd5b5061043260048036036020811015610adf57600080fd5b50356001600160a01b03166121e0565b348015610afb57600080fd5b5061043261224f565b348015610b1057600080fd5b50610449612275565b348015610b2557600080fd5b50610449612335565b348015610b3a57600080fd5b5061047061233b565b348015610b4f57600080fd5b5061043260048036036020811015610b6657600080fd5b50356001600160a01b031661234a565b348015610b8257600080fd5b506104496123b7565b348015610b9757600080fd5b5061043260048036036020811015610bae57600080fd5b50356001600160a01b0316612402565b348015610bca57600080fd5b50610449612471565b348015610bdf57600080fd5b50610470612477565b348015610bf457600080fd5b50610432612486565b348015610c0957600080fd5b5061047061261c565b348015610c1e57600080fd5b5061043260048036036020811015610c3557600080fd5b503561262b565b348015610c4857600080fd5b5061043260048036036020811015610c5f57600080fd5b5035612949565b348015610c7257600080fd5b50610432612b36565b348015610c8757600080fd5b50610470612b4b565b348015610c9c57600080fd5b50610552612b5a565b6008546001600160a01b03163314610cf2576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600380546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b600080610d2561147e565b90506000610d536ec097ce7bc90715b34b9f1000000000670de0b6b3a764000084900363ffffffff612bb316565b925050505b90565b73c00e94cb662c3520282e6f5717214004a7f2688881565b73d513d22422a3062bd342ae374b4b9c20e0a9a07481565b600080610d96611c5c565b90506000610da2611b36565b9050610d53828263ffffffff612bfc16565b620186a081565b6008546001600160a01b0316331480610dde5750600a546001600160a01b031633145b610e1d576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b6001600160a01b03166000908152601160205260409020805460ff19169055565b600b546001600160a01b03163314610e89576040805162461bcd60e51b81526020600482015260096024820152682174696d656c6f636b60b81b604482015290519081900360640190fd5b600255565b734ddc2d193948926d02f9b1fe9e1daa0718270ed581565b60035460ff1681565b6040805180820190915260128152715374726174656779436d706455736463563160701b602082015290565b600b546060906001600160a01b03163314610f29576040805162461bcd60e51b81526020600482015260096024820152682174696d656c6f636b60b81b604482015290519081900360640190fd5b6001600160a01b038316610f6e576040805162461bcd60e51b8152602060048201526007602482015266085d185c99d95d60ca1b604482015290519081900360640190fd5b600080835160208501866113885a03f43d6040519250601f19601f6020830101168301604052808352806000602085013e811560018114610fae57610fb5565b8160208501fd5b50505092915050565b6005546001600160a01b031681565b600a546001600160a01b031681565b600080516020613ead83398151915281565b600080610ff9611ab5565b90506000611005611d5e565b9050610d538261102383670de0b6b3a764000063ffffffff612c3e16565b9063ffffffff612bb316565b60008061103a61147e565b905061107581611023600e5461102368056bc75e2d6310000061106960b6600d54612c3e90919063ffffffff16565b9063ffffffff612c3e16565b91505090565b6009546001600160a01b031633146110c8576040805162461bcd60e51b815260206004820152600b60248201526a10b1b7b73a3937b63632b960a91b604482015290519081900360640190fd5b600554604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561111357600080fd5b505afa158015611127573d6000803e3d6000fd5b505050506040513d602081101561113d57600080fd5b50519050818110156111765761116161115c838363ffffffff612bfc16565b612c97565b9150611173828263ffffffff612f5016565b91505b6000611194620186a061102360025486612c3e90919063ffffffff16565b905060006111b4620186a061102360015487612c3e90919063ffffffff16565b60035490915060ff161515600114156111f7576000806111e26111dd858563ffffffff612f5016565b612faa565b915091506111f08282612fc2565b505061130d565b60095460408051638d8f1e6760e01b81529051611282926001600160a01b031691638d8f1e67916004808301926020929190829003018186803b15801561123d57600080fd5b505afa158015611251573d6000803e3d6000fd5b505050506040513d602081101561126757600080fd5b50516005546001600160a01b0316908463ffffffff6130fe16565b600954604080516361d027b360e01b8152905161130d926001600160a01b0316916361d027b3916004808301926020929190829003018186803b1580156112c857600080fd5b505afa1580156112dc573d6000803e3d6000fd5b505050506040513d60208110156112f257600080fd5b50516005546001600160a01b0316908363ffffffff6130fe16565b60095460055460408051632988bb9f60e21b81526001600160a01b0392831660048201529051600093929092169163a622ee7c91602480820192602092909190829003018186803b15801561136157600080fd5b505afa158015611375573d6000803e3d6000fd5b505050506040513d602081101561138b57600080fd5b505190506001600160a01b0381166113d3576040805162461bcd60e51b8152602060048201526006602482015265085d985d5b1d60d21b604482015290519081900360640190fd5b611410816113f7846113eb898863ffffffff612bfc16565b9063ffffffff612bfc16565b6005546001600160a01b0316919063ffffffff6130fe16565b5050505050565b6008546001600160a01b031633148061143a5750600a546001600160a01b031633145b611479576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600d55565b600080611489611576565b90506000610d536114b3600e54611023670de0b6b3a7640000600d54612c3e90919063ffffffff16565b839063ffffffff612bfc16565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6008546001600160a01b03163314806115135750600a546001600160a01b031633145b611552576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b6001600160a01b03166000908152601160205260409020805460ff19166001179055565b60408051638e8f294b60e01b8152600080516020613ead833981519152600482015281516000928392733d9819210a31b4961b30ef54be2aed79b9c9cd3b92638e8f294b92602480840193919291829003018186803b1580156115d857600080fd5b505afa1580156115ec573d6000803e3d6000fd5b505050506040513d604081101561160257600080fd5b506020015191505090565b3332148061162557506008546001600160a01b031633145b8061163a5750600a546001600160a01b031633145b61164357600080fd5b60408051600180825281830190925260609160208083019080368337019050509050600080516020613ead8339815191528160008151811061168157fe5b6001600160a01b039092166020928302919091018201526040805162e1ed9760e51b8152306004820181815260248301938452855160448401528551733d9819210a31b4961b30ef54be2aed79b9c9cd3b95631c3db2e0959394889492606490910191858101910280838360005b838110156117075781810151838201526020016116ef565b505050509050019350505050600060405180830381600087803b15801561172d57600080fd5b505af1158015611741573d6000803e3d6000fd5b5050604080516370a0823160e01b815230600482015290516000935073c00e94cb662c3520282e6f5717214004a7f2688892506370a0823191602480820192602092909190829003018186803b15801561179a57600080fd5b505afa1580156117ae573d6000803e3d6000fd5b505050506040513d60208110156117c457600080fd5b5051905080156117fa576005546117fa9073c00e94cb662c3520282e6f5717214004a7f26888906001600160a01b031683613155565b600554604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561184557600080fd5b505afa158015611859573d6000803e3d6000fd5b505050506040513d602081101561186f57600080fd5b5051600080549192509061189390620186a09061102390859063ffffffff612c3e16565b60035490915060ff16151560011480156118ad5750600081115b156118cd576005546118c8906001600160a01b031682612fc2565b611962565b811561196257600954604080516361d027b360e01b81529051611962926001600160a01b0316916361d027b3916004808301926020929190829003018186803b15801561191957600080fd5b505afa15801561192d573d6000803e3d6000fd5b505050506040513d602081101561194357600080fd5b50516000546113f790620186a09061102390879063ffffffff612c3e16565b811561197057611970612486565b50505050565b6007546001600160a01b031681565b6000600080516020613ead8339815191526001600160a01b03831614156119dd576040805162461bcd60e51b815260206004820152600760248201526610b1aa37b5b2b760c91b604482015290519081900360640190fd5b6119e682613755565b92915050565b6004546001600160a01b031681565b6008546001600160a01b0316331480611a1e5750600a546001600160a01b031633145b611a5d576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600f55565b6008546001600160a01b031681565b600080611a7c611ab5565b90506000611a88611d5e565b9050610d53611a9d838363ffffffff612bfc16565b61102384670de0b6b3a764000063ffffffff612c3e16565b60408051633af9e66960e01b81523060048201529051600091600080516020613ead83398151915291633af9e6699160248082019260209290919082900301818787803b158015611b0557600080fd5b505af1158015611b19573d6000803e3d6000fd5b505050506040513d6020811015611b2f57600080fd5b5051905090565b604080516395dd919360e01b81523060048201529051600091600080516020613ead833981519152916395dd919391602480820192602092909190829003018186803b158015611b8557600080fd5b505afa158015611b19573d6000803e3d6000fd5b733d9819210a31b4961b30ef54be2aed79b9c9cd3b81565b600b546001600160a01b03163314611bfc576040805162461bcd60e51b81526020600482015260096024820152682174696d656c6f636b60b81b604482015290519081900360640190fd5b600055565b6000611c22611c0e610d8b565b611c166123b7565b9063ffffffff612f5016565b905090565b600080611c32611576565b90506000610d536114b3601054611023670de0b6b3a7640000600f54612c3e90919063ffffffff16565b604080516361bfb47160e11b8152306004820152905160009182918291600080516020613ead8339815191529163c37f68e291602480820192608092909190829003018186803b158015611caf57600080fd5b505afa158015611cc3573d6000803e3d6000fd5b505050506040513d6080811015611cd957600080fd5b50602080820151606090920151604080519283019052808252919350909150600090611d059084613886565b94505050505090565b600b546001600160a01b03163314611d59576040805162461bcd60e51b81526020600482015260096024820152682174696d656c6f636b60b81b604482015290519081900360640190fd5b600155565b604080516305eff7ef60e21b81523060048201529051600091600080516020613ead833981519152916317bfdfbc9160248082019260209290919082900301818787803b158015611b0557600080fd5b6009546000906001600160a01b03163314611dfe576040805162461bcd60e51b815260206004820152600b60248201526a10b1b7b73a3937b63632b960a91b604482015290519081900360640190fd5b611e066138da565b600554604080516370a0823160e01b815230600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b158015611e5157600080fd5b505afa158015611e65573d6000803e3d6000fd5b505050506040513d6020811015611e7b57600080fd5b505160095460055460408051632988bb9f60e21b81526001600160a01b0392831660048201529051939450600093919092169163a622ee7c916024808301926020929190829003018186803b158015611ed357600080fd5b505afa158015611ee7573d6000803e3d6000fd5b505050506040513d6020811015611efd57600080fd5b505190506001600160a01b038116611f45576040805162461bcd60e51b8152602060048201526006602482015265085d985d5b1d60d21b604482015290519081900360640190fd5b600554611f62906001600160a01b0316828463ffffffff6130fe16565b5090565b60005481565b600b546001600160a01b03163314611fb7576040805162461bcd60e51b81526020600482015260096024820152682174696d656c6f636b60b81b604482015290519081900360640190fd5b600980546001600160a01b0319166001600160a01b0392909216919091179055565b6008546001600160a01b03163314612026576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b6003805460ff1916911515919091179055565b600080612044611ab5565b90506000610da2611d5e565b60008061205b611ab5565b90506000612067611d5e565b60408051638e8f294b60e01b8152600080516020613ead83398151915260048201528151929350600092733d9819210a31b4961b30ef54be2aed79b9c9cd3b92638e8f294b9260248082019391829003018186803b1580156120c857600080fd5b505afa1580156120dc573d6000803e3d6000fd5b505050506040513d60408110156120f257600080fd5b5060200151905061212361271061102361270f611069866113eb670de0b6b3a7640000858b8a63ffffffff612c3e16565b935050505090565b600080612136610d1a565b9050612154670de0b6b3a7640000611023858463ffffffff612c3e16565b9150505b919050565b6008546001600160a01b031633146121aa576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b60035461010090046001600160a01b031681565b6008546001600160a01b0316331461222d576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600880546001600160a01b0319166001600160a01b0392909216919091179055565b6000612259612039565b905060006122668261212b565b905061227181612949565b5050565b60408051631ea6374160e01b815273c00e94cb662c3520282e6f5717214004a7f268886004820152733d9819210a31b4961b30ef54be2aed79b9c9cd3b60248201523060448201529051600091829173d513d22422a3062bd342ae374b4b9c20e0a9a07491631ea6374191606480830192608092919082900301818787803b15801561230057600080fd5b505af1158015612314573d6000803e3d6000fd5b505050506040513d608081101561232a57600080fd5b506060015191505090565b60025481565b600c546001600160a01b031681565b600b546001600160a01b03163314612395576040805162461bcd60e51b81526020600482015260096024820152682174696d656c6f636b60b81b604482015290519081900360640190fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b600554604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015611b8557600080fd5b6008546001600160a01b0316331461244f576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b60015481565b6006546001600160a01b031681565b600554604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156124d157600080fd5b505afa1580156124e5573d6000803e3d6000fd5b505050506040513d60208110156124fb57600080fd5b50519050801561261957600554612531906001600160a01b0316600080516020613ead833981519152600063ffffffff6138e516565b60055461255c906001600160a01b0316600080516020613ead8339815191528363ffffffff6138e516565b600080516020613ead8339815191526001600160a01b031663a0712d68826040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156125b057600080fd5b505af11580156125c4573d6000803e3d6000fd5b505050506040513d60208110156125da57600080fd5b505115612619576040805162461bcd60e51b81526020600482015260086024820152670859195c1bdcda5d60c21b604482015290519081900360640190fd5b50565b600b546001600160a01b031681565b3360009081526011602052604090205460ff168061264857503330145b8061265d5750600a546001600160a01b031633145b8061267257506008546001600160a01b031633145b6126ae576040805162461bcd60e51b8152602060048201526008602482015267216b65657065727360c01b604482015290519081900360640190fd5b60006126b8612039565b905060006126c4611ab5565b90508183101580156126d65750808311155b612715576040805162461bcd60e51b815260206004820152600b60248201526a2164656c6576657261676560a81b604482015290519081900360640190fd5b600061271f612050565b90505b83612733838363ffffffff612bfc16565b101561274c57612749828563ffffffff612bfc16565b90505b600080516020613ead8339815191526001600160a01b031663852a12e3826040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156127a057600080fd5b505af11580156127b4573d6000803e3d6000fd5b505050506040513d60208110156127ca57600080fd5b505115612808576040805162461bcd60e51b81526020600482015260076024820152662172656465656d60c81b604482015290519081900360640190fd5b61283c73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48600080516020613ead833981519152600063ffffffff6138e516565b61286f73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48600080516020613ead8339815191528363ffffffff6138e516565b600080516020613ead8339815191526001600160a01b0316630e752702826040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156128c357600080fd5b505af11580156128d7573d6000803e3d6000fd5b505050506040513d60208110156128ed57600080fd5b50511561292a576040805162461bcd60e51b815260206004820152600660248201526521726570617960d01b604482015290519081900360640190fd5b61293a828263ffffffff612bfc16565b91508382116127225750505050565b3360009081526011602052604090205460ff168061296657503330145b8061297b5750600a546001600160a01b031633145b8061299057506008546001600160a01b031633145b6129cc576040805162461bcd60e51b8152602060048201526008602482015267216b65657065727360c01b604482015290519081900360640190fd5b60006129d6610d1a565b905060006129e2612039565b9050808310158015612a0f5750612a0b670de0b6b3a7640000611023838563ffffffff612c3e16565b8311155b612a4c576040805162461bcd60e51b8152602060048201526009602482015268216c6576657261676560b81b604482015290519081900360640190fd5b600080612a57611ab5565b90505b8481101561141057612a6a612050565b915084612a7d828463ffffffff612f5016565b1115612a9657612a93858263ffffffff612bfc16565b91505b600080516020613ead8339815191526001600160a01b031663c5ebeaec836040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015612aea57600080fd5b505af1158015612afe573d6000803e3d6000fd5b505050506040513d6020811015612b1457600080fd5b50612b1f9050612486565b612b2f818363ffffffff612f5016565b9050612a5a565b6000612b40612039565b90506126198161262b565b6009546001600160a01b031681565b600080612b65610fee565b90506000612b71611c27565b905080821115612baa576000612b85612039565b90506000612b928261212b565b9050612b9d8161262b565b6001945050505050610d58565b60009250505090565b6000612bf583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506139f8565b9392505050565b6000612bf583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613a9a565b600082612c4d575060006119e6565b82820282848281612c5a57fe5b0414612bf55760405162461bcd60e51b8152600401808060200182810382526021815260200180613e2c6021913960400191505060405180910390fd5b600080612ca26123b7565b9050600083905080600080516020613ead8339815191526001600160a01b0316633b1d21a26040518163ffffffff1660e01b815260040160206040518083038186803b158015612cf157600080fd5b505afa158015612d05573d6000803e3d6000fd5b505050506040513d6020811015612d1b57600080fd5b50511015612d62576040805162461bcd60e51b815260206004820152600f60248201526e21636173682d6c697175696469747960881b604482015290519081900360640190fd5b6000612d6c611d5e565b90506000612d78611ab5565b90506000612d84611a71565b90506000612da4670de0b6b3a7640000611023878563ffffffff612c3e16565b905083811115612e0657306001600160a01b031663f53f13506040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612de957600080fd5b505af1158015612dfd573d6000803e3d6000fd5b50505050612e6b565b3063eb514af9612e1c858463ffffffff612bfc16565b6040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015612e5257600080fd5b505af1158015612e66573d6000803e3d6000fd5b505050505b600080516020613ead8339815191526001600160a01b031663852a12e3866040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015612ebf57600080fd5b505af1158015612ed3573d6000803e3d6000fd5b505050506040513d6020811015612ee957600080fd5b505115612f27576040805162461bcd60e51b81526020600482015260076024820152662172656465656d60c81b604482015290519081900360640190fd5b6000612f316123b7565b9050612f43818863ffffffff612bfc16565b9998505050505050505050565b600082820183811015612bf5576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4891565b60035460ff1615156001141561227157600354612fef90839061010090046001600160a01b031683613155565b600354604080516370a0823160e01b8152306004820152905160009261010090046001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561303f57600080fd5b505afa158015613053573d6000803e3d6000fd5b505050506040513d602081101561306957600080fd5b50516004546003549192506130969161010090046001600160a01b0390811691168363ffffffff6130fe16565b6004805460408051635ad6dca560e11b8152928301849052516001600160a01b039091169163b5adb94a91602480830192600092919082900301818387803b1580156130e157600080fd5b505af11580156130f5573d6000803e3d6000fd5b50505050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052613150908490613af4565b505050565b6001600160a01b03821661316857600080fd5b600c54613189906001600160a01b038581169116600063ffffffff6138e516565b600c546131a9906001600160a01b0385811691168363ffffffff6138e516565b6003546060906001600160a01b03848116610100909204161480156131d5575060035460ff1615156001145b15613454576001600160a01b03841673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb481415613280576040805160028082526060820183529091602083019080368337019050509050838160008151811061322d57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050828160018151811061325b57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505061344f565b6007546001600160a01b03858116911614806132a957506006546001600160a01b038581169116145b1561338f5760408051600480825260a08201909252906020820160808036833701905050905083816000815181106132dd57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28160018151811061331f57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb488160028151811061336157fe5b60200260200101906001600160a01b031690816001600160a01b031681525050828160038151811061325b57fe5b60408051600380825260808201909252906020820160608036833701905050905083816000815181106133be57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb488160018151811061340057fe5b60200260200101906001600160a01b031690816001600160a01b031681525050828160028151811061342e57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250505b6135bc565b6001600160a01b03841673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2148061349b57506001600160a01b03831673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2145b156134fc57604080516002808252606082018352909160208301908036833701905050905083816000815181106134ce57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050828160018151811061342e57fe5b604080516003808252608082019092529060208201606080368337019050509050838160008151811061352b57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28160018151811061356d57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050828160028151811061359b57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250505b600c546001600160a01b03166338ed173983600084306135e342603c63ffffffff612f5016565b6040518663ffffffff1660e01b81526004018086815260200185815260200180602001846001600160a01b03166001600160a01b03168152602001838152602001828103825285818151815260200191508051906020019060200280838360005b8381101561365c578181015183820152602001613644565b505050509050019650505050505050600060405180830381600087803b15801561368557600080fd5b505af1158015613699573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156136c257600080fd5b81019080805160405193929190846401000000008211156136e257600080fd5b9083019060208201858111156136f757600080fd5b825186602082028301116401000000008211171561371457600080fd5b82525081516020918201928201910280838360005b83811015613741578181015183820152602001613729565b505050509050016040525050505050505050565b6009546000906001600160a01b031633146137a5576040805162461bcd60e51b815260206004820152600b60248201526a10b1b7b73a3937b63632b960a91b604482015290519081900360640190fd5b6005546001600160a01b03838116911614156137f1576040805162461bcd60e51b815260206004808301919091526024820152631dd85b9d60e21b604482015290519081900360640190fd5b604080516370a0823160e01b815230600482015290516001600160a01b038416916370a08231916024808301926020929190829003018186803b15801561383757600080fd5b505afa15801561384b573d6000803e3d6000fd5b505050506040513d602081101561386157600080fd5b5051600954909150612158906001600160a01b0384811691168363ffffffff6130fe16565b6000806000613893613e18565b61389d8686613ba5565b909250905060008260038111156138b057fe5b146138c157509150600090506138d3565b60006138cc82613c0d565b9350935050505b9250929050565b61261961115c610d8b565b80158061396b575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b15801561393d57600080fd5b505afa158015613951573d6000803e3d6000fd5b505050506040513d602081101561396757600080fd5b5051155b6139a65760405162461bcd60e51b8152600401808060200182810382526036815260200180613e776036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052613150908490613af4565b60008183613a845760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613a49578181015183820152602001613a31565b50505050905090810190601f168015613a765780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581613a9057fe5b0495945050505050565b60008184841115613aec5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613a49578181015183820152602001613a31565b505050900390565b6060613b49826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613c1c9092919063ffffffff16565b80519091501561315057808060200190516020811015613b6857600080fd5b50516131505760405162461bcd60e51b815260040180806020018281038252602a815260200180613e4d602a913960400191505060405180910390fd5b6000613baf613e18565b600080613bc0866000015186613c33565b90925090506000826003811115613bd357fe5b14613bf2575060408051602081019091526000815290925090506138d3565b60408051602081019091529081526000969095509350505050565b51670de0b6b3a7640000900490565b6060613c2b8484600085613c72565b949350505050565b60008083613c46575060009050806138d3565b83830283858281613c5357fe5b0414613c67575060029150600090506138d3565b6000925090506138d3565b6060613c7d85613ddf565b613cce576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b60208310613d0d5780518252601f199092019160209182019101613cee565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613d6f576040519150601f19603f3d011682016040523d82523d6000602084013e613d74565b606091505b50915091508115613d88579150613c2b9050565b805115613d985780518082602001fd5b60405162461bcd60e51b8152602060048201818152865160248401528651879391928392604401919085019080838360008315613a49578181015183820152602001613a31565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590613c2b575050151592915050565b604051806020016040528060008152509056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000000039aa39c021dfbae8fac545936693ac917d5e7563a2646970667358221220e8ac17c2cf4541cd119378e41606f4066a4b9eb7d7108a1d733c85dac3cd848e64736f6c6343000607003300000000000000000000000043229759e12efbe3e2a0fb0510b15e516d04644200000000000000000000000043229759e12efbe3e2a0fb0510b15e516d0464420000000000000000000000004bf5059065541a2b176500928e91fbfd0b121d070000000000000000000000005dae9b27313670663b34ac8bffd18825bb9df736
Deployed Bytecode
0x6080604052600436106103fa5760003560e01c80635fe3b56711610213578063a890dd9011610123578063cc32d176116100ab578063eb514af91161007a578063eb514af914610c12578063f4aa3a8d14610c3c578063f53f135014610c66578063f77c479114610c7b578063fff6cae914610c90576103fa565b8063cc32d17614610bbe578063ce7079ba14610bd3578063d0e30db014610be8578063d33219b414610bfd576103fa565b8063b635b8ae116100f2578063b635b8ae14610b19578063b9e3748914610b2e578063bdacb30314610b43578063c1a3d44c14610b76578063c7b9d53014610b8b576103fa565b8063a890dd9014610aa7578063ab033ea914610abc578063ac41ceb314610aef578063b01db4ec14610b04576103fa565b8063853828b6116101a65780639a9b567d116101755780639a9b567d146109f45780639c4b816314610a205780639eb52f6114610a35578063a1e003e414610a4a578063a2d9f4dc14610a74576103fa565b8063853828b614610997578063857a52b81461077857806387788782146109ac57806392eefe9b146109c1576103fa565b806377da835a116101e257806377da835a1461094357806377e741c7146109585780637cc79113146104b65780638081e1cf14610982576103fa565b80635fe3b567146108da57806370897b23146108ef578063722713f7146109195780637396a6261461092e576103fa565b80632bfc9c231161030e5780634641257d116102a157806359bca6791161027057806359bca6791461085c5780635aa6e675146108865780635bfb92ce1461089b5780635c208490146108b05780635eefb092146108c5576103fa565b80634641257d146107ea5780634a183ffc146107ff57806351cff8d914610814578063575a86b214610847576103fa565b80633e413bee116102dd5780633e413bee146107785780633fc8cef31461078d5780634032b72b146107a2578063463289ed146107d5576103fa565b80632bfc9c23146106fa5780632e1a7d4d1461070f578063302ab80d146107395780633c5dae9414610763576103fa565b806314e6ac09116103915780631cff79cd116103605780631cff79cd146105f05780631f1fcd51146106a65780631fe4a686146106bb57806320852ee7146106d05780632a99417d146106e5576103fa565b806314e6ac09146104fe57806315ac03fd14610528578063160d0da51461053d57806317d7de7c14610566576103fa565b806311588086116103cd57806311588086146104a157806313bd4b95146104b657806314a1fe02146104b657806314ae9f2e146104cb576103fa565b806305166eff146103ff5780630ea8b3bf14610434578063109d0af81461045b578063112666b71461048c575b600080fd5b34801561040b57600080fd5b506104326004803603602081101561042257600080fd5b50356001600160a01b0316610ca5565b005b34801561044057600080fd5b50610449610d1a565b60408051918252519081900360200190f35b34801561046757600080fd5b50610470610d5b565b604080516001600160a01b039092168252519081900360200190f35b34801561049857600080fd5b50610470610d73565b3480156104ad57600080fd5b50610449610d8b565b3480156104c257600080fd5b50610449610db4565b3480156104d757600080fd5b50610432600480360360208110156104ee57600080fd5b50356001600160a01b0316610dbb565b34801561050a57600080fd5b506104326004803603602081101561052157600080fd5b5035610e3e565b34801561053457600080fd5b50610470610e8e565b34801561054957600080fd5b50610552610ea6565b604080519115158252519081900360200190f35b34801561057257600080fd5b5061057b610eaf565b6040805160208082528351818301528351919283929083019185019080838360005b838110156105b557818101518382015260200161059d565b50505050905090810190601f1680156105e25780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61057b6004803603604081101561060657600080fd5b6001600160a01b03823516919081019060408101602082013564010000000081111561063157600080fd5b82018360208201111561064357600080fd5b8035906020019184600183028401116401000000008311171561066557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610edb945050505050565b3480156106b257600080fd5b50610470610fbe565b3480156106c757600080fd5b50610470610fcd565b3480156106dc57600080fd5b50610470610fdc565b3480156106f157600080fd5b50610449610fee565b34801561070657600080fd5b5061044961102f565b34801561071b57600080fd5b506104326004803603602081101561073257600080fd5b503561107b565b34801561074557600080fd5b506104326004803603602081101561075c57600080fd5b5035611417565b34801561076f57600080fd5b5061044961147e565b34801561078457600080fd5b506104706114c0565b34801561079957600080fd5b506104706114d8565b3480156107ae57600080fd5b50610432600480360360208110156107c557600080fd5b50356001600160a01b03166114f0565b3480156107e157600080fd5b50610449611576565b3480156107f657600080fd5b5061043261160d565b34801561080b57600080fd5b50610470611976565b34801561082057600080fd5b506104496004803603602081101561083757600080fd5b50356001600160a01b0316611985565b34801561085357600080fd5b506104706119ec565b34801561086857600080fd5b506104326004803603602081101561087f57600080fd5b50356119fb565b34801561089257600080fd5b50610470611a62565b3480156108a757600080fd5b50610449611a71565b3480156108bc57600080fd5b50610449611ab5565b3480156108d157600080fd5b50610449611b36565b3480156108e657600080fd5b50610470611b99565b3480156108fb57600080fd5b506104326004803603602081101561091257600080fd5b5035611bb1565b34801561092557600080fd5b50610449611c01565b34801561093a57600080fd5b50610449611c27565b34801561094f57600080fd5b50610449611c5c565b34801561096457600080fd5b506104326004803603602081101561097b57600080fd5b5035611d0e565b34801561098e57600080fd5b50610449611d5e565b3480156109a357600080fd5b50610449611dae565b3480156109b857600080fd5b50610449611f66565b3480156109cd57600080fd5b50610432600480360360208110156109e457600080fd5b50356001600160a01b0316611f6c565b348015610a0057600080fd5b5061043260048036036020811015610a1757600080fd5b50351515611fd9565b348015610a2c57600080fd5b50610449612039565b348015610a4157600080fd5b50610449612050565b348015610a5657600080fd5b5061044960048036036020811015610a6d57600080fd5b503561212b565b348015610a8057600080fd5b5061043260048036036020811015610a9757600080fd5b50356001600160a01b031661215d565b348015610ab357600080fd5b506104706121cc565b348015610ac857600080fd5b5061043260048036036020811015610adf57600080fd5b50356001600160a01b03166121e0565b348015610afb57600080fd5b5061043261224f565b348015610b1057600080fd5b50610449612275565b348015610b2557600080fd5b50610449612335565b348015610b3a57600080fd5b5061047061233b565b348015610b4f57600080fd5b5061043260048036036020811015610b6657600080fd5b50356001600160a01b031661234a565b348015610b8257600080fd5b506104496123b7565b348015610b9757600080fd5b5061043260048036036020811015610bae57600080fd5b50356001600160a01b0316612402565b348015610bca57600080fd5b50610449612471565b348015610bdf57600080fd5b50610470612477565b348015610bf457600080fd5b50610432612486565b348015610c0957600080fd5b5061047061261c565b348015610c1e57600080fd5b5061043260048036036020811015610c3557600080fd5b503561262b565b348015610c4857600080fd5b5061043260048036036020811015610c5f57600080fd5b5035612949565b348015610c7257600080fd5b50610432612b36565b348015610c8757600080fd5b50610470612b4b565b348015610c9c57600080fd5b50610552612b5a565b6008546001600160a01b03163314610cf2576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600380546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b600080610d2561147e565b90506000610d536ec097ce7bc90715b34b9f1000000000670de0b6b3a764000084900363ffffffff612bb316565b925050505b90565b73c00e94cb662c3520282e6f5717214004a7f2688881565b73d513d22422a3062bd342ae374b4b9c20e0a9a07481565b600080610d96611c5c565b90506000610da2611b36565b9050610d53828263ffffffff612bfc16565b620186a081565b6008546001600160a01b0316331480610dde5750600a546001600160a01b031633145b610e1d576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b6001600160a01b03166000908152601160205260409020805460ff19169055565b600b546001600160a01b03163314610e89576040805162461bcd60e51b81526020600482015260096024820152682174696d656c6f636b60b81b604482015290519081900360640190fd5b600255565b734ddc2d193948926d02f9b1fe9e1daa0718270ed581565b60035460ff1681565b6040805180820190915260128152715374726174656779436d706455736463563160701b602082015290565b600b546060906001600160a01b03163314610f29576040805162461bcd60e51b81526020600482015260096024820152682174696d656c6f636b60b81b604482015290519081900360640190fd5b6001600160a01b038316610f6e576040805162461bcd60e51b8152602060048201526007602482015266085d185c99d95d60ca1b604482015290519081900360640190fd5b600080835160208501866113885a03f43d6040519250601f19601f6020830101168301604052808352806000602085013e811560018114610fae57610fb5565b8160208501fd5b50505092915050565b6005546001600160a01b031681565b600a546001600160a01b031681565b600080516020613ead83398151915281565b600080610ff9611ab5565b90506000611005611d5e565b9050610d538261102383670de0b6b3a764000063ffffffff612c3e16565b9063ffffffff612bb316565b60008061103a61147e565b905061107581611023600e5461102368056bc75e2d6310000061106960b6600d54612c3e90919063ffffffff16565b9063ffffffff612c3e16565b91505090565b6009546001600160a01b031633146110c8576040805162461bcd60e51b815260206004820152600b60248201526a10b1b7b73a3937b63632b960a91b604482015290519081900360640190fd5b600554604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561111357600080fd5b505afa158015611127573d6000803e3d6000fd5b505050506040513d602081101561113d57600080fd5b50519050818110156111765761116161115c838363ffffffff612bfc16565b612c97565b9150611173828263ffffffff612f5016565b91505b6000611194620186a061102360025486612c3e90919063ffffffff16565b905060006111b4620186a061102360015487612c3e90919063ffffffff16565b60035490915060ff161515600114156111f7576000806111e26111dd858563ffffffff612f5016565b612faa565b915091506111f08282612fc2565b505061130d565b60095460408051638d8f1e6760e01b81529051611282926001600160a01b031691638d8f1e67916004808301926020929190829003018186803b15801561123d57600080fd5b505afa158015611251573d6000803e3d6000fd5b505050506040513d602081101561126757600080fd5b50516005546001600160a01b0316908463ffffffff6130fe16565b600954604080516361d027b360e01b8152905161130d926001600160a01b0316916361d027b3916004808301926020929190829003018186803b1580156112c857600080fd5b505afa1580156112dc573d6000803e3d6000fd5b505050506040513d60208110156112f257600080fd5b50516005546001600160a01b0316908363ffffffff6130fe16565b60095460055460408051632988bb9f60e21b81526001600160a01b0392831660048201529051600093929092169163a622ee7c91602480820192602092909190829003018186803b15801561136157600080fd5b505afa158015611375573d6000803e3d6000fd5b505050506040513d602081101561138b57600080fd5b505190506001600160a01b0381166113d3576040805162461bcd60e51b8152602060048201526006602482015265085d985d5b1d60d21b604482015290519081900360640190fd5b611410816113f7846113eb898863ffffffff612bfc16565b9063ffffffff612bfc16565b6005546001600160a01b0316919063ffffffff6130fe16565b5050505050565b6008546001600160a01b031633148061143a5750600a546001600160a01b031633145b611479576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600d55565b600080611489611576565b90506000610d536114b3600e54611023670de0b6b3a7640000600d54612c3e90919063ffffffff16565b839063ffffffff612bfc16565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6008546001600160a01b03163314806115135750600a546001600160a01b031633145b611552576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b6001600160a01b03166000908152601160205260409020805460ff19166001179055565b60408051638e8f294b60e01b8152600080516020613ead833981519152600482015281516000928392733d9819210a31b4961b30ef54be2aed79b9c9cd3b92638e8f294b92602480840193919291829003018186803b1580156115d857600080fd5b505afa1580156115ec573d6000803e3d6000fd5b505050506040513d604081101561160257600080fd5b506020015191505090565b3332148061162557506008546001600160a01b031633145b8061163a5750600a546001600160a01b031633145b61164357600080fd5b60408051600180825281830190925260609160208083019080368337019050509050600080516020613ead8339815191528160008151811061168157fe5b6001600160a01b039092166020928302919091018201526040805162e1ed9760e51b8152306004820181815260248301938452855160448401528551733d9819210a31b4961b30ef54be2aed79b9c9cd3b95631c3db2e0959394889492606490910191858101910280838360005b838110156117075781810151838201526020016116ef565b505050509050019350505050600060405180830381600087803b15801561172d57600080fd5b505af1158015611741573d6000803e3d6000fd5b5050604080516370a0823160e01b815230600482015290516000935073c00e94cb662c3520282e6f5717214004a7f2688892506370a0823191602480820192602092909190829003018186803b15801561179a57600080fd5b505afa1580156117ae573d6000803e3d6000fd5b505050506040513d60208110156117c457600080fd5b5051905080156117fa576005546117fa9073c00e94cb662c3520282e6f5717214004a7f26888906001600160a01b031683613155565b600554604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561184557600080fd5b505afa158015611859573d6000803e3d6000fd5b505050506040513d602081101561186f57600080fd5b5051600080549192509061189390620186a09061102390859063ffffffff612c3e16565b60035490915060ff16151560011480156118ad5750600081115b156118cd576005546118c8906001600160a01b031682612fc2565b611962565b811561196257600954604080516361d027b360e01b81529051611962926001600160a01b0316916361d027b3916004808301926020929190829003018186803b15801561191957600080fd5b505afa15801561192d573d6000803e3d6000fd5b505050506040513d602081101561194357600080fd5b50516000546113f790620186a09061102390879063ffffffff612c3e16565b811561197057611970612486565b50505050565b6007546001600160a01b031681565b6000600080516020613ead8339815191526001600160a01b03831614156119dd576040805162461bcd60e51b815260206004820152600760248201526610b1aa37b5b2b760c91b604482015290519081900360640190fd5b6119e682613755565b92915050565b6004546001600160a01b031681565b6008546001600160a01b0316331480611a1e5750600a546001600160a01b031633145b611a5d576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600f55565b6008546001600160a01b031681565b600080611a7c611ab5565b90506000611a88611d5e565b9050610d53611a9d838363ffffffff612bfc16565b61102384670de0b6b3a764000063ffffffff612c3e16565b60408051633af9e66960e01b81523060048201529051600091600080516020613ead83398151915291633af9e6699160248082019260209290919082900301818787803b158015611b0557600080fd5b505af1158015611b19573d6000803e3d6000fd5b505050506040513d6020811015611b2f57600080fd5b5051905090565b604080516395dd919360e01b81523060048201529051600091600080516020613ead833981519152916395dd919391602480820192602092909190829003018186803b158015611b8557600080fd5b505afa158015611b19573d6000803e3d6000fd5b733d9819210a31b4961b30ef54be2aed79b9c9cd3b81565b600b546001600160a01b03163314611bfc576040805162461bcd60e51b81526020600482015260096024820152682174696d656c6f636b60b81b604482015290519081900360640190fd5b600055565b6000611c22611c0e610d8b565b611c166123b7565b9063ffffffff612f5016565b905090565b600080611c32611576565b90506000610d536114b3601054611023670de0b6b3a7640000600f54612c3e90919063ffffffff16565b604080516361bfb47160e11b8152306004820152905160009182918291600080516020613ead8339815191529163c37f68e291602480820192608092909190829003018186803b158015611caf57600080fd5b505afa158015611cc3573d6000803e3d6000fd5b505050506040513d6080811015611cd957600080fd5b50602080820151606090920151604080519283019052808252919350909150600090611d059084613886565b94505050505090565b600b546001600160a01b03163314611d59576040805162461bcd60e51b81526020600482015260096024820152682174696d656c6f636b60b81b604482015290519081900360640190fd5b600155565b604080516305eff7ef60e21b81523060048201529051600091600080516020613ead833981519152916317bfdfbc9160248082019260209290919082900301818787803b158015611b0557600080fd5b6009546000906001600160a01b03163314611dfe576040805162461bcd60e51b815260206004820152600b60248201526a10b1b7b73a3937b63632b960a91b604482015290519081900360640190fd5b611e066138da565b600554604080516370a0823160e01b815230600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b158015611e5157600080fd5b505afa158015611e65573d6000803e3d6000fd5b505050506040513d6020811015611e7b57600080fd5b505160095460055460408051632988bb9f60e21b81526001600160a01b0392831660048201529051939450600093919092169163a622ee7c916024808301926020929190829003018186803b158015611ed357600080fd5b505afa158015611ee7573d6000803e3d6000fd5b505050506040513d6020811015611efd57600080fd5b505190506001600160a01b038116611f45576040805162461bcd60e51b8152602060048201526006602482015265085d985d5b1d60d21b604482015290519081900360640190fd5b600554611f62906001600160a01b0316828463ffffffff6130fe16565b5090565b60005481565b600b546001600160a01b03163314611fb7576040805162461bcd60e51b81526020600482015260096024820152682174696d656c6f636b60b81b604482015290519081900360640190fd5b600980546001600160a01b0319166001600160a01b0392909216919091179055565b6008546001600160a01b03163314612026576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b6003805460ff1916911515919091179055565b600080612044611ab5565b90506000610da2611d5e565b60008061205b611ab5565b90506000612067611d5e565b60408051638e8f294b60e01b8152600080516020613ead83398151915260048201528151929350600092733d9819210a31b4961b30ef54be2aed79b9c9cd3b92638e8f294b9260248082019391829003018186803b1580156120c857600080fd5b505afa1580156120dc573d6000803e3d6000fd5b505050506040513d60408110156120f257600080fd5b5060200151905061212361271061102361270f611069866113eb670de0b6b3a7640000858b8a63ffffffff612c3e16565b935050505090565b600080612136610d1a565b9050612154670de0b6b3a7640000611023858463ffffffff612c3e16565b9150505b919050565b6008546001600160a01b031633146121aa576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b60035461010090046001600160a01b031681565b6008546001600160a01b0316331461222d576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600880546001600160a01b0319166001600160a01b0392909216919091179055565b6000612259612039565b905060006122668261212b565b905061227181612949565b5050565b60408051631ea6374160e01b815273c00e94cb662c3520282e6f5717214004a7f268886004820152733d9819210a31b4961b30ef54be2aed79b9c9cd3b60248201523060448201529051600091829173d513d22422a3062bd342ae374b4b9c20e0a9a07491631ea6374191606480830192608092919082900301818787803b15801561230057600080fd5b505af1158015612314573d6000803e3d6000fd5b505050506040513d608081101561232a57600080fd5b506060015191505090565b60025481565b600c546001600160a01b031681565b600b546001600160a01b03163314612395576040805162461bcd60e51b81526020600482015260096024820152682174696d656c6f636b60b81b604482015290519081900360640190fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b600554604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015611b8557600080fd5b6008546001600160a01b0316331461244f576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b60015481565b6006546001600160a01b031681565b600554604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156124d157600080fd5b505afa1580156124e5573d6000803e3d6000fd5b505050506040513d60208110156124fb57600080fd5b50519050801561261957600554612531906001600160a01b0316600080516020613ead833981519152600063ffffffff6138e516565b60055461255c906001600160a01b0316600080516020613ead8339815191528363ffffffff6138e516565b600080516020613ead8339815191526001600160a01b031663a0712d68826040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156125b057600080fd5b505af11580156125c4573d6000803e3d6000fd5b505050506040513d60208110156125da57600080fd5b505115612619576040805162461bcd60e51b81526020600482015260086024820152670859195c1bdcda5d60c21b604482015290519081900360640190fd5b50565b600b546001600160a01b031681565b3360009081526011602052604090205460ff168061264857503330145b8061265d5750600a546001600160a01b031633145b8061267257506008546001600160a01b031633145b6126ae576040805162461bcd60e51b8152602060048201526008602482015267216b65657065727360c01b604482015290519081900360640190fd5b60006126b8612039565b905060006126c4611ab5565b90508183101580156126d65750808311155b612715576040805162461bcd60e51b815260206004820152600b60248201526a2164656c6576657261676560a81b604482015290519081900360640190fd5b600061271f612050565b90505b83612733838363ffffffff612bfc16565b101561274c57612749828563ffffffff612bfc16565b90505b600080516020613ead8339815191526001600160a01b031663852a12e3826040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156127a057600080fd5b505af11580156127b4573d6000803e3d6000fd5b505050506040513d60208110156127ca57600080fd5b505115612808576040805162461bcd60e51b81526020600482015260076024820152662172656465656d60c81b604482015290519081900360640190fd5b61283c73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48600080516020613ead833981519152600063ffffffff6138e516565b61286f73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48600080516020613ead8339815191528363ffffffff6138e516565b600080516020613ead8339815191526001600160a01b0316630e752702826040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156128c357600080fd5b505af11580156128d7573d6000803e3d6000fd5b505050506040513d60208110156128ed57600080fd5b50511561292a576040805162461bcd60e51b815260206004820152600660248201526521726570617960d01b604482015290519081900360640190fd5b61293a828263ffffffff612bfc16565b91508382116127225750505050565b3360009081526011602052604090205460ff168061296657503330145b8061297b5750600a546001600160a01b031633145b8061299057506008546001600160a01b031633145b6129cc576040805162461bcd60e51b8152602060048201526008602482015267216b65657065727360c01b604482015290519081900360640190fd5b60006129d6610d1a565b905060006129e2612039565b9050808310158015612a0f5750612a0b670de0b6b3a7640000611023838563ffffffff612c3e16565b8311155b612a4c576040805162461bcd60e51b8152602060048201526009602482015268216c6576657261676560b81b604482015290519081900360640190fd5b600080612a57611ab5565b90505b8481101561141057612a6a612050565b915084612a7d828463ffffffff612f5016565b1115612a9657612a93858263ffffffff612bfc16565b91505b600080516020613ead8339815191526001600160a01b031663c5ebeaec836040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015612aea57600080fd5b505af1158015612afe573d6000803e3d6000fd5b505050506040513d6020811015612b1457600080fd5b50612b1f9050612486565b612b2f818363ffffffff612f5016565b9050612a5a565b6000612b40612039565b90506126198161262b565b6009546001600160a01b031681565b600080612b65610fee565b90506000612b71611c27565b905080821115612baa576000612b85612039565b90506000612b928261212b565b9050612b9d8161262b565b6001945050505050610d58565b60009250505090565b6000612bf583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506139f8565b9392505050565b6000612bf583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613a9a565b600082612c4d575060006119e6565b82820282848281612c5a57fe5b0414612bf55760405162461bcd60e51b8152600401808060200182810382526021815260200180613e2c6021913960400191505060405180910390fd5b600080612ca26123b7565b9050600083905080600080516020613ead8339815191526001600160a01b0316633b1d21a26040518163ffffffff1660e01b815260040160206040518083038186803b158015612cf157600080fd5b505afa158015612d05573d6000803e3d6000fd5b505050506040513d6020811015612d1b57600080fd5b50511015612d62576040805162461bcd60e51b815260206004820152600f60248201526e21636173682d6c697175696469747960881b604482015290519081900360640190fd5b6000612d6c611d5e565b90506000612d78611ab5565b90506000612d84611a71565b90506000612da4670de0b6b3a7640000611023878563ffffffff612c3e16565b905083811115612e0657306001600160a01b031663f53f13506040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612de957600080fd5b505af1158015612dfd573d6000803e3d6000fd5b50505050612e6b565b3063eb514af9612e1c858463ffffffff612bfc16565b6040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015612e5257600080fd5b505af1158015612e66573d6000803e3d6000fd5b505050505b600080516020613ead8339815191526001600160a01b031663852a12e3866040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015612ebf57600080fd5b505af1158015612ed3573d6000803e3d6000fd5b505050506040513d6020811015612ee957600080fd5b505115612f27576040805162461bcd60e51b81526020600482015260076024820152662172656465656d60c81b604482015290519081900360640190fd5b6000612f316123b7565b9050612f43818863ffffffff612bfc16565b9998505050505050505050565b600082820183811015612bf5576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4891565b60035460ff1615156001141561227157600354612fef90839061010090046001600160a01b031683613155565b600354604080516370a0823160e01b8152306004820152905160009261010090046001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561303f57600080fd5b505afa158015613053573d6000803e3d6000fd5b505050506040513d602081101561306957600080fd5b50516004546003549192506130969161010090046001600160a01b0390811691168363ffffffff6130fe16565b6004805460408051635ad6dca560e11b8152928301849052516001600160a01b039091169163b5adb94a91602480830192600092919082900301818387803b1580156130e157600080fd5b505af11580156130f5573d6000803e3d6000fd5b50505050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052613150908490613af4565b505050565b6001600160a01b03821661316857600080fd5b600c54613189906001600160a01b038581169116600063ffffffff6138e516565b600c546131a9906001600160a01b0385811691168363ffffffff6138e516565b6003546060906001600160a01b03848116610100909204161480156131d5575060035460ff1615156001145b15613454576001600160a01b03841673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb481415613280576040805160028082526060820183529091602083019080368337019050509050838160008151811061322d57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050828160018151811061325b57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505061344f565b6007546001600160a01b03858116911614806132a957506006546001600160a01b038581169116145b1561338f5760408051600480825260a08201909252906020820160808036833701905050905083816000815181106132dd57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28160018151811061331f57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb488160028151811061336157fe5b60200260200101906001600160a01b031690816001600160a01b031681525050828160038151811061325b57fe5b60408051600380825260808201909252906020820160608036833701905050905083816000815181106133be57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb488160018151811061340057fe5b60200260200101906001600160a01b031690816001600160a01b031681525050828160028151811061342e57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250505b6135bc565b6001600160a01b03841673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2148061349b57506001600160a01b03831673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2145b156134fc57604080516002808252606082018352909160208301908036833701905050905083816000815181106134ce57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050828160018151811061342e57fe5b604080516003808252608082019092529060208201606080368337019050509050838160008151811061352b57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28160018151811061356d57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050828160028151811061359b57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250505b600c546001600160a01b03166338ed173983600084306135e342603c63ffffffff612f5016565b6040518663ffffffff1660e01b81526004018086815260200185815260200180602001846001600160a01b03166001600160a01b03168152602001838152602001828103825285818151815260200191508051906020019060200280838360005b8381101561365c578181015183820152602001613644565b505050509050019650505050505050600060405180830381600087803b15801561368557600080fd5b505af1158015613699573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156136c257600080fd5b81019080805160405193929190846401000000008211156136e257600080fd5b9083019060208201858111156136f757600080fd5b825186602082028301116401000000008211171561371457600080fd5b82525081516020918201928201910280838360005b83811015613741578181015183820152602001613729565b505050509050016040525050505050505050565b6009546000906001600160a01b031633146137a5576040805162461bcd60e51b815260206004820152600b60248201526a10b1b7b73a3937b63632b960a91b604482015290519081900360640190fd5b6005546001600160a01b03838116911614156137f1576040805162461bcd60e51b815260206004808301919091526024820152631dd85b9d60e21b604482015290519081900360640190fd5b604080516370a0823160e01b815230600482015290516001600160a01b038416916370a08231916024808301926020929190829003018186803b15801561383757600080fd5b505afa15801561384b573d6000803e3d6000fd5b505050506040513d602081101561386157600080fd5b5051600954909150612158906001600160a01b0384811691168363ffffffff6130fe16565b6000806000613893613e18565b61389d8686613ba5565b909250905060008260038111156138b057fe5b146138c157509150600090506138d3565b60006138cc82613c0d565b9350935050505b9250929050565b61261961115c610d8b565b80158061396b575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b15801561393d57600080fd5b505afa158015613951573d6000803e3d6000fd5b505050506040513d602081101561396757600080fd5b5051155b6139a65760405162461bcd60e51b8152600401808060200182810382526036815260200180613e776036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052613150908490613af4565b60008183613a845760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613a49578181015183820152602001613a31565b50505050905090810190601f168015613a765780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581613a9057fe5b0495945050505050565b60008184841115613aec5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613a49578181015183820152602001613a31565b505050900390565b6060613b49826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613c1c9092919063ffffffff16565b80519091501561315057808060200190516020811015613b6857600080fd5b50516131505760405162461bcd60e51b815260040180806020018281038252602a815260200180613e4d602a913960400191505060405180910390fd5b6000613baf613e18565b600080613bc0866000015186613c33565b90925090506000826003811115613bd357fe5b14613bf2575060408051602081019091526000815290925090506138d3565b60408051602081019091529081526000969095509350505050565b51670de0b6b3a7640000900490565b6060613c2b8484600085613c72565b949350505050565b60008083613c46575060009050806138d3565b83830283858281613c5357fe5b0414613c67575060029150600090506138d3565b6000925090506138d3565b6060613c7d85613ddf565b613cce576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b60208310613d0d5780518252601f199092019160209182019101613cee565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613d6f576040519150601f19603f3d011682016040523d82523d6000602084013e613d74565b606091505b50915091508115613d88579150613c2b9050565b805115613d985780518082602001fd5b60405162461bcd60e51b8152602060048201818152865160248401528651879391928392604401919085019080838360008315613a49578181015183820152602001613a31565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590613c2b575050151592915050565b604051806020016040528060008152509056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000000039aa39c021dfbae8fac545936693ac917d5e7563a2646970667358221220e8ac17c2cf4541cd119378e41606f4066a4b9eb7d7108a1d733c85dac3cd848e64736f6c63430006070033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000043229759e12efbe3e2a0fb0510b15e516d04644200000000000000000000000043229759e12efbe3e2a0fb0510b15e516d0464420000000000000000000000004bf5059065541a2b176500928e91fbfd0b121d070000000000000000000000005dae9b27313670663b34ac8bffd18825bb9df736
-----Decoded View---------------
Arg [0] : _governance (address): 0x43229759E12eFbe3e2A0fB0510B15e516d046442
Arg [1] : _strategist (address): 0x43229759E12eFbe3e2A0fB0510B15e516d046442
Arg [2] : _controller (address): 0x4bF5059065541A2B176500928e91FBfD0B121d07
Arg [3] : _timelock (address): 0x5DAe9B27313670663B34Ac8BfFD18825bB9Df736
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 00000000000000000000000043229759e12efbe3e2a0fb0510b15e516d046442
Arg [1] : 00000000000000000000000043229759e12efbe3e2a0fb0510b15e516d046442
Arg [2] : 0000000000000000000000004bf5059065541a2b176500928e91fbfd0b121d07
Arg [3] : 0000000000000000000000005dae9b27313670663b34ac8bffd18825bb9df736
Deployed Bytecode Sourcemap
74825:14262:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;9;2:12;59718:143:0;;5:9:-1;2:2;;;27:1;24;17:12;2:2;59718:143:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;59718:143:0;-1:-1:-1;;;;;59718:143:0;;:::i;:::-;;78890:276;;5:9:-1;2:2;;;27:1;24;17:12;2:2;78890:276:0;;;:::i;:::-;;;;;;;;;;;;;;;;75145:73;;5:9:-1;2:2;;;27:1;24;17:12;2:2;75145:73:0;;;:::i;:::-;;;;-1:-1:-1;;;;;75145:73:0;;;;;;;;;;;;;;74985;;5:9:-1;2:2;;;27:1;24;17:12;2:2;74985:73:0;;;:::i;77370:206::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;77370:206:0;;;:::i;56516:43::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;56516:43:0;;;:::i;81884:213::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;81884:213:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;81884:213:0;-1:-1:-1;;;;;81884:213:0;;:::i;58585:151::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;58585:151:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;58585:151:0;;:::i;75306:75::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;75306:75:0;;;:::i;56590:34::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;56590:34:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;76766:112;;5:9:-1;2:2;;;27:1;24;17:12;2:2;76766:112:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;76766:112:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63477:1053;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;;;;;63477:1053:0;;;;;;;;;;;;;;;27:11:-1;11:28;;8:2;;;52:1;49;42:12;8:2;63477:1053:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;63477:1053:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;63477:1053:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;63477:1053:0;;-1:-1:-1;63477:1053:0;;-1:-1:-1;;;;;63477:1053:0:i;56710:19::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;56710:19:0;;;:::i;57173:25::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;57173:25:0;;;:::i;75225:74::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;75225:74:0;;;:::i;80328:195::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;80328:195:0;;;:::i;79417:240::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;79417:240:0;;;:::i;60830:1243::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;60830:1243:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;60830:1243:0;;:::i;82105:284::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;82105:284:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;82105:284:0;;:::i;77956:347::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;77956:347:0;;;:::i;75065:73::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;75065:73:0;;;:::i;56736:::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;56736:73:0;;;:::i;81667:209::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;81667:209:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;81667:209:0;-1:-1:-1;;;;;81667:209:0;;:::i;78654:172::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;78654:172:0;;;:::i;86101:1026::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;86101:1026:0;;;:::i;57005:73::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;57005:73:0;;;:::i;88894:190::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;88894:190:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;88894:190:0;-1:-1:-1;;;;;88894:190:0;;:::i;56660:25::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;56660:25:0;;;:::i;82397:254::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;82397:254:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;82397:254:0;;:::i;57109:25::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;57109:25:0;;;:::i;81413:215::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;81413:215:0;;;:::i;80734:123::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;80734:123:0;;;:::i;77230:132::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;77230:132:0;;;:::i;74889:89::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;74889:89:0;;;:::i;58907:167::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;58907:167:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;58907:167:0;;:::i;58360:113::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;58360:113:0;;;:::i;78311:335::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;78311:335:0;;;:::i;76886:336::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;76886:336:0;;;:::i;58744:155::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;58744:155:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;58744:155:0;;:::i;80865:124::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;80865:124:0;;;:::i;62624:440::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;62624:440:0;;;:::i;56192:37::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;56192:37:0;;;:::i;59559:151::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;59559:151:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;59559:151:0;-1:-1:-1;;;;;59559:151:0;;:::i;59869:168::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;59869:168:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;59869:168:0;;;;:::i;80531:195::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;80531:195:0;;;:::i;80997:408::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;80997:408:0;;;:::i;77720:228::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;77720:228:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;77720:228:0;;:::i;60045:155::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;60045:155:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;60045:155:0;-1:-1:-1;;;;;60045:155:0;;:::i;56631:22::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;56631:22:0;;;:::i;59245:155::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;59245:155:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;59245:155:0;-1:-1:-1;;;;;59245:155:0;;:::i;83311:216::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;83311:216:0;;;:::i;80068:252::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;80068:252:0;;;:::i;56479:30::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;56479:30:0;;;:::i;57249:72::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;57249:72:0;;;:::i;59408:143::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;59408:143:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;59408:143:0;-1:-1:-1;;;;;59408:143:0;;:::i;58163:118::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;58163:118:0;;;:::i;59082:155::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;59082:155:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;59082:155:0;-1:-1:-1;;;;;59082:155:0;;:::i;56387:32::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;56387:32:0;;;:::i;56927:71::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;56927:71:0;;;:::i;87135:313::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;87135:313:0;;;:::i;57205:23::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;57205:23:0;;;:::i;84897:1051::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;84897:1051:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;84897:1051:0;;:::i;83639:986::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;83639:986:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;83639:986:0;;:::i;84633:150::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;84633:150:0;;;:::i;57141:25::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;57141:25:0;;;:::i;82817:486::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;82817:486:0;;;:::i;59718:143::-;59798:10;;-1:-1:-1;;;;;59798:10:0;59784;:24;59776:48;;;;;-1:-1:-1;;;59776:48:0;;;;;;;;;;;;-1:-1:-1;;;59776:48:0;;;;;;;;;;;;;;;59835:7;:18;;-1:-1:-1;;;;;59835:18:0;;;;;-1:-1:-1;;;;;;59835:18:0;;;;;;;;;59718:143::o;78890:276::-;78937:7;78957:29;78989:26;:24;:26::i;:::-;78957:58;-1:-1:-1;79066:16:0;79085:47;79093:4;79103;:28;;;79085:47;:17;:47;:::i;:::-;79066:66;-1:-1:-1;;;78890:276:0;;:::o;75145:73::-;75176:42;75145:73;:::o;74985:::-;75016:42;74985:73;:::o;77370:206::-;77425:7;77445:16;77464:17;:15;:17::i;:::-;77445:36;;77492:16;77511:17;:15;:17::i;:::-;77492:36;-1:-1:-1;77546:22:0;:8;77492:36;77546:22;:12;:22;:::i;56516:43::-;56553:6;56516:43;:::o;81884:213::-;81977:10;;-1:-1:-1;;;;;81977:10:0;81963;:24;;:52;;-1:-1:-1;82005:10:0;;-1:-1:-1;;;;;82005:10:0;81991;:24;81963:52;81941:113;;;;;-1:-1:-1;;;81941:113:0;;;;;;;;;;;;-1:-1:-1;;;81941:113:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;82065:16:0;82084:5;82065:16;;;:7;:16;;;;;:24;;-1:-1:-1;;82065:24:0;;;81884:213::o;58585:151::-;58671:8;;-1:-1:-1;;;;;58671:8:0;58657:10;:22;58649:44;;;;;-1:-1:-1;;;58649:44:0;;;;;;;;;;;;-1:-1:-1;;;58649:44:0;;;;;;;;;;;;;;;58704:10;:24;58585:151::o;75306:75::-;75339:42;75306:75;:::o;56590:34::-;;;;;;:::o;76766:112::-;76843:27;;;;;;;;;;;;-1:-1:-1;;;76843:27:0;;;;76766:112;:::o;63477:1053::-;63643:8;;63582:21;;-1:-1:-1;;;;;63643:8:0;63629:10;:22;63621:44;;;;;-1:-1:-1;;;63621:44:0;;;;;;;;;;;;-1:-1:-1;;;63621:44:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;63684:21:0;;63676:41;;;;;-1:-1:-1;;;63676:41:0;;;;;;;;;;;;-1:-1:-1;;;63676:41:0;;;;;;;;;;;;;;;63994:1;63974;63949:5;63943:12;63919:4;63912:5;63908:16;63882:7;63858:4;63851:5;63847:16;63816:194;64036:16;64086:4;64080:11;64068:23;;64203:4;64199:9;64192:4;64185;64179;64175:15;64171:26;64167:42;64157:8;64153:57;64130:4;64105:120;64256:4;64246:8;64239:22;64314:4;64311:1;64304:4;64294:8;64290:19;64275:44;64349:9;64342:17;64382:1;64377:135;;;;64335:177;;64377:135;64488:4;64481;64471:8;64467:19;64460:33;64335:177;;;;63784:739;;;;:::o;56710:19::-;;;-1:-1:-1;;;;;56710:19:0;;:::o;57173:25::-;;;-1:-1:-1;;;;;57173:25:0;;:::o;75225:74::-;-1:-1:-1;;;;;;;;;;;75225:74:0;:::o;80328:195::-;80368:7;80388:16;80407:13;:11;:13::i;:::-;80388:32;;80431:16;80450:13;:11;:13::i;:::-;80431:32;-1:-1:-1;80483:32:0;80506:8;80483:18;80431:32;80496:4;80483:18;:12;:18;:::i;:::-;:22;:32;:22;:32;:::i;79417:240::-;79466:7;79486:21;79510:26;:24;:26::i;:::-;79486:50;;79554:95;79635:13;79555:74;79602:26;;79555:42;79592:4;79555:32;79583:3;79555:23;;:27;;:32;;;;:::i;:::-;:36;:42;:36;:42;:::i;79554:95::-;79547:102;;;79417:240;:::o;60830:1243::-;60907:10;;-1:-1:-1;;;;;60907:10:0;60893;:24;60885:48;;;;;-1:-1:-1;;;60885:48:0;;;;;;;;;;;;-1:-1:-1;;;60885:48:0;;;;;;;;;;;;;;;60970:4;;60963:37;;;-1:-1:-1;;;60963:37:0;;60994:4;60963:37;;;;;;60944:16;;-1:-1:-1;;;;;60970:4:0;;60963:22;;:37;;;;;;;;;;;;;;60970:4;60963:37;;;2:2:-1;;;;27:1;24;17:12;2:2;60963:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;60963:37:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;60963:37:0;;-1:-1:-1;61015:18:0;;;61011:143;;;61060:36;61074:21;:7;61086:8;61074:21;:11;:21;:::i;:::-;61060:13;:36::i;:::-;61050:46;-1:-1:-1;61121:21:0;61050:46;61133:8;61121:21;:11;:21;:::i;:::-;61111:31;;61011:143;61170:15;61188:39;56553:6;61188:23;61200:10;;61188:7;:11;;:23;;;;:::i;:39::-;61170:57;;61238:20;61261:41;56464:6;61261:24;61273:11;;61261:7;:11;;:24;;;;:::i;:41::-;61319:14;;61238:64;;-1:-1:-1;61319:14:0;;:22;;:14;:22;61315:480;;;61421:25;;61474:48;61496:25;:7;61508:12;61496:25;:11;:25;:::i;:::-;61474:21;:48::i;:::-;61420:102;;;;61537:51;61554:17;61573:14;61537:16;:51::i;:::-;61315:480;;;;;61662:10;;61650:33;;;-1:-1:-1;;;61650:33:0;;;;61624:69;;-1:-1:-1;;;;;61662:10:0;;61650:31;;:33;;;;;;;;;;;;;;61662:10;61650:33;;;2:2:-1;;;;27:1;24;17:12;2:2;61650:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;61650:33:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;61650:33:0;61631:4;;-1:-1:-1;;;;;61631:4:0;;61685:7;61624:69;:25;:69;:::i;:::-;61746:10;;61734:34;;;-1:-1:-1;;;61734:34:0;;;;61708:75;;-1:-1:-1;;;;;61746:10:0;;61734:32;;:34;;;;;;;;;;;;;;61746:10;61734:34;;;2:2:-1;;;;27:1;24;17:12;2:2;61734:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;61734:34:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;61734:34:0;61715:4;;-1:-1:-1;;;;;61715:4:0;;61770:12;61708:75;:25;:75;:::i;:::-;61844:10;;61871:4;;61832:45;;;-1:-1:-1;;;61832:45:0;;-1:-1:-1;;;;;61871:4:0;;;61832:45;;;;;;61815:14;;61844:10;;;;;61832:30;;:45;;;;;;;;;;;;;;;61844:10;61832:45;;;2:2:-1;;;;27:1;24;17:12;2:2;61832:45:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;61832:45:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;61832:45:0;;-1:-1:-1;;;;;;61896:20:0;;61888:39;;;;;-1:-1:-1;;;61888:39:0;;;;;;;;;;;;-1:-1:-1;;;61888:39:0;;;;;;;;;;;;;;;61992:73;62018:6;62026:38;62051:12;62026:20;:7;62038;62026:20;:11;:20;:::i;:::-;:24;:38;:24;:38;:::i;:::-;61999:4;;-1:-1:-1;;;;;61999:4:0;;61992:73;;:25;:73;:::i;:::-;60830:1243;;;;;:::o;82105:284::-;82243:10;;-1:-1:-1;;;;;82243:10:0;82229;:24;;:52;;-1:-1:-1;82271:10:0;;-1:-1:-1;;;;;82271:10:0;82257;:24;82229:52;82207:113;;;;;-1:-1:-1;;;82207:113:0;;;;;;;;;;;;-1:-1:-1;;;82207:113:0;;;;;;;;;;;;;;;82331:23;:50;82105:284::o;77956:347::-;78013:7;78033:17;78053:20;:18;:20::i;:::-;78033:40;;78134:21;78158:104;78186:65;78224:26;;78186:33;78214:4;78186:23;;:27;;:33;;;;:::i;:65::-;78158:9;;:104;:13;:104;:::i;75065:73::-;75096:42;75065:73;:::o;56736:::-;56767:42;56736:73;:::o;81667:209::-;81757:10;;-1:-1:-1;;;;;81757:10:0;81743;:24;;:52;;-1:-1:-1;81785:10:0;;-1:-1:-1;;;;;81785:10:0;81771;:24;81743:52;81721:113;;;;;-1:-1:-1;;;81721:113:0;;;;;;;;;;;;-1:-1:-1;;;81721:113:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;81845:16:0;;;;;:7;:16;;;;;:23;;-1:-1:-1;;81845:23:0;81864:4;81845:23;;;81667:209::o;78654:172::-;78749:40;;;-1:-1:-1;;;78749:40:0;;-1:-1:-1;;;;;;;;;;;78749:40:0;;;;;;78705:7;;;;74936:42;;78749:33;;:40;;;;;;;;;;;;;74936:42;78749:40;;;2:2:-1;;;;27:1;24;17:12;2:2;78749:40:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;78749:40:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;78749:40:0;;;;-1:-1:-1;;78654:172:0;:::o;86101:1026::-;57982:10;57996:9;57982:23;;:68;;-1:-1:-1;58040:10:0;;-1:-1:-1;;;;;58040:10:0;58026;:24;57982:68;:113;;;-1:-1:-1;58085:10:0;;-1:-1:-1;;;;;58085:10:0;58071;:24;57982:113;57960:146;;12:1:-1;9;2:12;57960:146:0;86189:16:::1;::::0;;86203:1:::1;86189:16:::0;;;;;::::1;::::0;;;86162:24:::1;::::0;86189:16:::1;::::0;;::::1;::::0;;109:14:-1::1;86189:16:0::0;88:42:-1::1;144:17;::::0;-1:-1;86189:16:0::1;86162:43;;-1:-1:-1::0;;;;;;;;;;;86216:7:0::1;86224:1;86216:10;;;;;;;;-1:-1:-1::0;;;;;86216:18:0;;::::1;:10;::::0;;::::1;::::0;;;;;;:18;86247:59:::1;::::0;;-1:-1:-1;;;86247:59:0;;86291:4:::1;86247:59;::::0;::::1;::::0;;;;;;;;;;;;;;;;;74936:42:::1;::::0;86247:35:::1;::::0;86291:4;;86298:7;;86247:59;;;;;;;;::::1;::::0;::::1;::::0;;;-1:-1:-1;8:100:::1;33:3;30:1;27:10;8:100;;;90:11:::0;;::::1;84:18:::0;71:11;;::::1;64:39:::0;52:2:::1;45:10;8:100;;;12:14;86247:59:0;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::1;2:2;86247:59:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;-1:-1:::0;;86333:37:0::1;::::0;;-1:-1:-1;;;86333:37:0;;86364:4:::1;86333:37;::::0;::::1;::::0;;;86317:13:::1;::::0;-1:-1:-1;75176:42:0::1;::::0;-1:-1:-1;86333:22:0::1;::::0;:37;;;;;::::1;::::0;;;;;;;;;75176:42;86333:37;::::1;;2:2:-1::0;::::1;;;27:1;24::::0;17:12:::1;2:2;86333:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;86333:37:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;-1:-1:::0;86333:37:0;;-1:-1:-1;86385:9:0;;86381:73:::1;;86430:4;::::0;86411:31:::1;::::0;75176:42:::1;::::0;-1:-1:-1;;;;;86430:4:0::1;86436:5:::0;86411:12:::1;:31::i;:::-;86489:4;::::0;86482:37:::1;::::0;;-1:-1:-1;;;86482:37:0;;86513:4:::1;86482:37;::::0;::::1;::::0;;;86466:13:::1;::::0;-1:-1:-1;;;;;86489:4:0::1;::::0;86482:22:::1;::::0;:37;;;;;::::1;::::0;;;;;;;;86489:4;86482:37;::::1;;2:2:-1::0;::::1;;;27:1;24::::0;17:12:::1;2:2;86482:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;86482:37:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;-1:-1:::0;86482:37:0;86530:22:::1;86565:14:::0;;86482:37;;-1:-1:-1;86530:22:0;86555:45:::1;::::0;56277:6:::1;::::0;86555:25:::1;::::0;86482:37;;86555:25:::1;:9;:25;:::i;:45::-;86617:14;::::0;86530:70;;-1:-1:-1;86617:14:0::1;;:22;;:14:::0;:22:::1;:44:::0;::::1;;;;86660:1;86643:14;:18;86617:44;86613:400;;;86695:4;::::0;86678:38:::1;::::0;-1:-1:-1;;;;;86695:4:0::1;86701:14:::0;86678:16:::1;:38::i;:::-;86613:400;;;86794:9:::0;;86790:212:::1;;86916:10;::::0;86904:34:::1;::::0;;-1:-1:-1;;;86904:34:0;;;;86878:108:::1;::::0;-1:-1:-1;;;;;86916:10:0::1;::::0;86904:32:::1;::::0;:34:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;86916:10;86904:34;::::1;;2:2:-1::0;::::1;;;27:1;24::::0;17:12:::1;2:2;86904:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;86904:34:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;-1:-1:::0;86904:34:0;86950:14:::1;::::0;86940:45:::1;::::0;56277:6:::1;::::0;86940:25:::1;::::0;:5;;:25:::1;:9;:25;:::i;86878:108::-;87073:9:::0;;87069:51:::1;;87099:9;:7;:9::i;:::-;58117:1;;;;86101:1026::o:0;57005:73::-;;;-1:-1:-1;;;;;57005:73:0;;:::o;88894:190::-;88954:15;-1:-1:-1;;;;;;;;;;;;;;;;88990:24:0;;;;88982:44;;;;;-1:-1:-1;;;88982:44:0;;;;;;;;;;;;-1:-1:-1;;;88982:44:0;;;;;;;;;;;;;;;89047:29;89069:6;89047:21;:29::i;:::-;89037:39;88894:190;-1:-1:-1;;88894:190:0:o;56660:25::-;;;-1:-1:-1;;;;;56660:25:0;;:::o;82397:254::-;82513:10;;-1:-1:-1;;;;;82513:10:0;82499;:24;;:52;;-1:-1:-1;82541:10:0;;-1:-1:-1;;;;;82541:10:0;82527;:24;82499:52;82477:113;;;;;-1:-1:-1;;;82477:113:0;;;;;;;;;;;;-1:-1:-1;;;82477:113:0;;;;;;;;;;;;;;;82601:19;:42;82397:254::o;57109:25::-;;;-1:-1:-1;;;;;57109:25:0;;:::o;81413:215::-;81459:7;81479:16;81498:13;:11;:13::i;:::-;81479:32;;81522:16;81541:13;:11;:13::i;:::-;81522:32;-1:-1:-1;81574:46:0;81597:22;:8;81522:32;81597:22;:12;:22;:::i;:::-;81574:18;:8;81587:4;81574:18;:12;:18;:::i;80734:123::-;80800:49;;;-1:-1:-1;;;80800:49:0;;80843:4;80800:49;;;;;;80773:7;;-1:-1:-1;;;;;;;;;;;75257:42:0;80800:34;;:49;;;;;;;;;;;;;;;80773:7;75257:42;80800:49;;;2:2:-1;;;;27:1;24;17:12;2:2;80800:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;80800:49:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;80800:49:0;;-1:-1:-1;80734:123:0;:::o;77230:132::-;77305:49;;;-1:-1:-1;;;77305:49:0;;77348:4;77305:49;;;;;;77278:7;;-1:-1:-1;;;;;;;;;;;75257:42:0;77305:34;;:49;;;;;;;;;;;;;;;75257:42;77305:49;;;2:2:-1;;;;27:1;24;17:12;2:2;77305:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;74889:89:0;74936:42;74889:89;:::o;58907:167::-;59001:8;;-1:-1:-1;;;;;59001:8:0;58987:10;:22;58979:44;;;;;-1:-1:-1;;;58979:44:0;;;;;;;;;;;;-1:-1:-1;;;58979:44:0;;;;;;;;;;;;;;;59034:14;:32;58907:167::o;58360:113::-;58402:7;58429:36;58449:15;:13;:15::i;:::-;58429;:13;:15::i;:::-;:19;:36;:19;:36;:::i;:::-;58422:43;;58360:113;:::o;78311:335::-;78364:7;78384:17;78404:20;:18;:20::i;:::-;78384:40;;78485:21;78509:96;78537:57;78571:22;;78537:29;78561:4;78537:19;;:23;;:29;;;;:::i;76886:336::-;77002:62;;;-1:-1:-1;;;77002:62:0;;77058:4;77002:62;;;;;;76934:7;;;;;;-1:-1:-1;;;;;;;;;;;75257:42:0;77002:47;;:62;;;;;;;;;;;;;;;75257:42;77002:62;;;2:2:-1;;;;27:1;24;17:12;2:2;77002:62:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;77002:62:0;;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;77002:62:0;;;;;;;;;;;77127:29;;;;;;;;;;77002:62;;-1:-1:-1;77002:62:0;;-1:-1:-1;77080:11:0;;77095:96;;77002:62;77095:17;:96::i;:::-;77077:114;-1:-1:-1;;;;;76886:336:0;:::o;58744:155::-;58832:8;;-1:-1:-1;;;;;58832:8:0;58818:10;:22;58810:44;;;;;-1:-1:-1;;;58810:44:0;;;;;;;;;;;;-1:-1:-1;;;58810:44:0;;;;;;;;;;;;;;;58865:11;:26;58744:155::o;80865:124::-;80931:50;;;-1:-1:-1;;;80931:50:0;;80975:4;80931:50;;;;;;80904:7;;-1:-1:-1;;;;;;;;;;;75257:42:0;80931:35;;:50;;;;;;;;;;;;;;;80904:7;75257:42;80931:50;;;2:2:-1;;;;27:1;24;17:12;62624:440:0;62715:10;;62665:15;;-1:-1:-1;;;;;62715:10:0;62701;:24;62693:48;;;;;-1:-1:-1;;;62693:48:0;;;;;;;;;;;;-1:-1:-1;;;62693:48:0;;;;;;;;;;;;;;;62752:14;:12;:14::i;:::-;62796:4;;62789:37;;;-1:-1:-1;;;62789:37:0;;62820:4;62789:37;;;;;;-1:-1:-1;;;;;62796:4:0;;;;62789:22;;:37;;;;;;;;;;;;;;;62796:4;62789:37;;;2:2:-1;;;;27:1;24;17:12;2:2;62789:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62789:37:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;62789:37:0;62868:10;;62895:4;;62856:45;;;-1:-1:-1;;;62856:45:0;;-1:-1:-1;;;;;62895:4:0;;;62856:45;;;;;;62789:37;;-1:-1:-1;62839:14:0;;62868:10;;;;;62856:30;;:45;;;;;62789:37;;62856:45;;;;;;;62868:10;62856:45;;;2:2:-1;;;;27:1;24;17:12;2:2;62856:45:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62856:45:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;62856:45:0;;-1:-1:-1;;;;;;62920:20:0;;62912:39;;;;;-1:-1:-1;;;62912:39:0;;;;;;;;;;;;-1:-1:-1;;;62912:39:0;;;;;;;;;;;;;;;63021:4;;63014:42;;-1:-1:-1;;;;;63021:4:0;63040:6;63048:7;63014:42;:25;:42;:::i;:::-;62624:440;;:::o;56192:37::-;;;;:::o;59559:151::-;59645:8;;-1:-1:-1;;;;;59645:8:0;59631:10;:22;59623:44;;;;;-1:-1:-1;;;59623:44:0;;;;;;;;;;;;-1:-1:-1;;;59623:44:0;;;;;;;;;;;;;;;59678:10;:24;;-1:-1:-1;;;;;;59678:24:0;-1:-1:-1;;;;;59678:24:0;;;;;;;;;;59559:151::o;59869:168::-;59960:10;;-1:-1:-1;;;;;59960:10:0;59946;:24;59938:48;;;;;-1:-1:-1;;;59938:48:0;;;;;;;;;;;;-1:-1:-1;;;59938:48:0;;;;;;;;;;;;;;;59997:14;:32;;-1:-1:-1;;59997:32:0;;;;;;;;;;59869:168::o;80531:195::-;80581:7;80601:16;80620:13;:11;:13::i;:::-;80601:32;;80644:16;80663:13;:11;:13::i;80997:408::-;81038:7;81058:16;81077:13;:11;:13::i;:::-;81058:32;;81101:16;81120:13;:11;:13::i;:::-;81170:40;;;-1:-1:-1;;;81170:40:0;;-1:-1:-1;;;;;;;;;;;81170:40:0;;;;;;81101:32;;-1:-1:-1;81149:17:0;;74936:42;;81170:33;;:40;;;;;;;;;;;74936:42;81170:40;;;2:2:-1;;;;27:1;24;17:12;2:2;81170:40:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;81170:40:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;81170:40:0;;;;-1:-1:-1;81297:100:0;81377:5;81297:57;81349:4;81297:47;81335:8;81297:33;81325:4;81297:57;:8;81170:40;81297:23;:12;:23;:::i;:100::-;81277:120;;;;;80997:408;:::o;77720:228::-;77825:7;77850:16;77869;:14;:16::i;:::-;77850:35;-1:-1:-1;77903:37:0;77935:4;77903:27;:13;77850:35;77903:27;:17;:27;:::i;:37::-;77896:44;;;77720:228;;;;:::o;60045:155::-;60131:10;;-1:-1:-1;;;;;60131:10:0;60117;:24;60109:48;;;;;-1:-1:-1;;;60109:48:0;;;;;;;;;;;;-1:-1:-1;;;60109:48:0;;;;;;;;;;;;;;;60168:10;:24;;-1:-1:-1;;;;;;60168:24:0;-1:-1:-1;;;;;60168:24:0;;;;;;;;;;60045:155::o;56631:22::-;;;;;;-1:-1:-1;;;;;56631:22:0;;:::o;59245:155::-;59331:10;;-1:-1:-1;;;;;59331:10:0;59317;:24;59309:48;;;;;-1:-1:-1;;;59309:48:0;;;;;;;;;;;;-1:-1:-1;;;59309:48:0;;;;;;;;;;;;;;;59368:10;:24;;-1:-1:-1;;;;;;59368:24:0;-1:-1:-1;;;;;59368:24:0;;;;;;;;;;59245:155::o;83311:216::-;83354:25;83382:24;:22;:24::i;:::-;83354:52;;83417:19;83439:43;83464:17;83439:24;:43::i;:::-;83417:65;;83493:26;83507:11;83493:13;:26::i;:::-;83311:216;;:::o;80068:252::-;80156:129;;;-1:-1:-1;;;80156:129:0;;75176:42;80156:129;;;;74936:42;80156:129;;;;80269:4;80156:129;;;;;;80110:7;;;;75016:42;;80156:45;;:129;;;;;;;;;;;;;;80110:7;75016:42;80156:129;;;2:2:-1;;;;27:1;24;17:12;2:2;80156:129:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;80156:129:0;;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;80156:129:0;;;;-1:-1:-1;;80068:252:0;:::o;56479:30::-;;;;:::o;57249:72::-;;;-1:-1:-1;;;;;57249:72:0;;:::o;59408:143::-;59490:8;;-1:-1:-1;;;;;59490:8:0;59476:10;:22;59468:44;;;;;-1:-1:-1;;;59468:44:0;;;;;;;;;;;;-1:-1:-1;;;59468:44:0;;;;;;;;;;;;;;;59523:8;:20;;-1:-1:-1;;;;;;59523:20:0;-1:-1:-1;;;;;59523:20:0;;;;;;;;;;59408:143::o;58163:118::-;58243:4;;58236:37;;;-1:-1:-1;;;58236:37:0;;58267:4;58236:37;;;;;;58209:7;;-1:-1:-1;;;;;58243:4:0;;58236:22;;:37;;;;;;;;;;;;;;58243:4;58236:37;;;2:2:-1;;;;27:1;24;17:12;59082:155:0;59168:10;;-1:-1:-1;;;;;59168:10:0;59154;:24;59146:48;;;;;-1:-1:-1;;;59146:48:0;;;;;;;;;;;;-1:-1:-1;;;59146:48:0;;;;;;;;;;;;;;;59205:10;:24;;-1:-1:-1;;;;;;59205:24:0;-1:-1:-1;;;;;59205:24:0;;;;;;;;;;59082:155::o;56387:32::-;;;;:::o;56927:71::-;;;-1:-1:-1;;;;;56927:71:0;;:::o;87135:313::-;87204:4;;87197:37;;;-1:-1:-1;;;87197:37:0;;87228:4;87197:37;;;;;;87181:13;;-1:-1:-1;;;;;87204:4:0;;87197:22;;:37;;;;;;;;;;;;;;87204:4;87197:37;;;2:2:-1;;;;27:1;24;17:12;2:2;87197:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;87197:37:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;87197:37:0;;-1:-1:-1;87249:9:0;;87245:196;;87282:4;;87275:34;;-1:-1:-1;;;;;87282:4:0;-1:-1:-1;;;;;;;;;;;87307:1:0;87275:34;:24;:34;:::i;:::-;87331:4;;87324:38;;-1:-1:-1;;;;;87331:4:0;-1:-1:-1;;;;;;;;;;;87356:5:0;87324:38;:24;:38;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;87385:19:0;;87405:5;87385:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;87385:26:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;87385:26:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;87385:26:0;:31;87377:52;;;;;-1:-1:-1;;;87377:52:0;;;;;;;;;;;;-1:-1:-1;;;87377:52:0;;;;;;;;;;;;;;;87135:313;:::o;57205:23::-;;;-1:-1:-1;;;;;57205:23:0;;:::o;84897:1051::-;76524:10;76516:19;;;;:7;:19;;;;;;;;;:67;;-1:-1:-1;76556:10:0;76578:4;76556:27;76516:67;:112;;;-1:-1:-1;76618:10:0;;-1:-1:-1;;;;;76618:10:0;76604;:24;76516:112;:157;;;-1:-1:-1;76663:10:0;;-1:-1:-1;;;;;76663:10:0;76649;:24;76516:157;76494:215;;;;;-1:-1:-1;;;76494:215:0;;;;;;;;;;;;-1:-1:-1;;;76494:215:0;;;;;;;;;;;;;;;84975:25:::1;85003:24;:22;:24::i;:::-;84975:52;;85038:16;85057:13;:11;:13::i;:::-;85038:32;;85120:17;85103:13;:34;;:63;;;;;85158:8;85141:13;:25;;85103:63;85081:124;;;::::0;;-1:-1:-1;;;85081:124:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;85081:124:0;;;;;;;;;;;;;::::1;;85305:23;85331:15;:13;:15::i;:::-;85305:41;;85357:584;85411:13:::0;85379:29:::1;:8:::0;85392:15;85379:29:::1;:12;:29;:::i;:::-;:45;85375:131;;;85463:27;:8:::0;85476:13;85463:27:::1;:12;:27;:::i;:::-;85445:45;;85375:131;-1:-1:-1::0;;;;;;;;;;;;;;;;85548:31:0::1;;85580:15;85548:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::1;2:2;85548:48:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;85548:48:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;-1:-1:::0;85548:48:0;:53;85522:122:::1;;;::::0;;-1:-1:-1;;;85522:122:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;85522:122:0;;;;;;;;;;;;;::::1;;85659:34;75096:42;-1:-1:-1::0;;;;;;;;;;;85691:1:0::1;85659:34;:24;:34;:::i;:::-;85708:48;75096:42;-1:-1:-1::0;;;;;;;;;;;85740:15:0;85708:48:::1;:24;:48;:::i;:::-;-1:-1:-1::0;;;;;;;;;;;;;;;;85779:26:0::1;;85806:15;85779:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::1;2:2;85779:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;85779:43:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;-1:-1:::0;85779:43:0;:48;85771:67:::1;;;::::0;;-1:-1:-1;;;85771:67:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;85771:67:0;;;;;;;;;;;;;::::1;;85866:29;:8:::0;85879:15;85866:29:::1;:12;:29;:::i;:::-;85855:40;;85926:13;85915:8;:24;85357:584;;76720:1;;;84897:1051:::0;:::o;83639:986::-;76524:10;76516:19;;;;:7;:19;;;;;;;;;:67;;-1:-1:-1;76556:10:0;76578:4;76556:27;76516:67;:112;;;-1:-1:-1;76618:10:0;;-1:-1:-1;;;;;76618:10:0;76604;:24;76516:112;:157;;;-1:-1:-1;76663:10:0;;-1:-1:-1;;;;;76663:10:0;76649;:24;76516:157;76494:215;;;;;-1:-1:-1;;;76494:215:0;;;;;;;;;;;;-1:-1:-1;;;76494:215:0;;;;;;;;;;;;;;;83783:16:::1;83802;:14;:16::i;:::-;83783:35;;83829:25;83857:24;:22;:24::i;:::-;83829:52;;83931:17;83914:13;:34;;:113;;;;-1:-1:-1::0;83986:41:0::1;84022:4;83986:31;:17:::0;84008:8;83986:31:::1;:21;:31;:::i;:41::-;83969:13;:58;;83914:113;83892:172;;;::::0;;-1:-1:-1;;;83892:172:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;83892:172:0;;;;;;;;;;;;;::::1;;84159:24;84194:16:::0;84213:13:::1;:11;:13::i;:::-;84194:32;;84237:381;84255:13;84244:8;:24;84237:381;;;84304:15;:13;:15::i;:::-;84285:34:::0;-1:-1:-1;84373:13:0;84340:30:::1;:8:::0;84285:34;84340:30:::1;:12;:30;:::i;:::-;:46;84336:133;;;84426:27;:13:::0;84444:8;84426:27:::1;:17;:27;:::i;:::-;84407:46;;84336:133;-1:-1:-1::0;;;;;;;;;;;;;;;;84485:21:0::1;;84507:16;84485:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::1;2:2;84485:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;84485:39:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;-1:-1:::0;84539:9:0::1;::::0;-1:-1:-1;84539:7:0::1;:9::i;:::-;84576:30;:8:::0;84589:16;84576:30:::1;:12;:30;:::i;:::-;84565:41;;84237:381;;84633:150:::0;84678:25;84706:24;:22;:24::i;:::-;84678:52;;84741:34;84757:17;84741:15;:34::i;57141:25::-;;;-1:-1:-1;;;;;57141:25:0;;:::o;82817:486::-;82849:4;82866:17;82886:14;:12;:14::i;:::-;82866:34;;82911:25;82939:22;:20;:22::i;:::-;82911:50;;83020:17;83008:9;:29;83004:267;;;83054:25;83082:24;:22;:24::i;:::-;83054:52;;83121:19;83143:43;83168:17;83143:24;:43::i;:::-;83121:65;;83203:28;83219:11;83203:15;:28::i;:::-;83255:4;83248:11;;;;;;;;83004:267;83290:5;83283:12;;;;82817:486;:::o;3274:132::-;3332:7;3359:39;3363:1;3366;3359:39;;;;;;;;;;;;;;;;;:3;:39::i;:::-;3352:46;3274:132;-1:-1:-1;;;3274:132:0:o;1437:136::-;1495:7;1522:43;1526:1;1529;1522:43;;;;;;;;;;;;;;;;;:3;:43::i;2327:471::-;2385:7;2630:6;2626:47;;-1:-1:-1;2660:1:0;2653:8;;2626:47;2697:5;;;2701:1;2697;:5;:1;2721:5;;;;;:10;2713:56;;;;-1:-1:-1;;;2713:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87456:1355;87550:7;87626:16;87645:15;:13;:15::i;:::-;87626:34;;87671:15;87689:7;87671:25;;87794:7;-1:-1:-1;;;;;;;;;;;;;;;;87766:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;87766:24:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;87766:24:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;87766:24:0;:35;;87758:63;;;;;-1:-1:-1;;;87758:63:0;;;;;;;;;;;;-1:-1:-1;;;87758:63:0;;;;;;;;;;;;;;;87891:16;87910:13;:11;:13::i;:::-;87891:32;;87934:16;87953:13;:11;:13::i;:::-;87934:32;;87977:19;87999:20;:18;:20::i;:::-;87977:42;-1:-1:-1;88030:24:0;88057:34;88086:4;88057:24;:7;87977:42;88057:24;:11;:24;:::i;:34::-;88030:61;;88232:8;88213:16;:27;88209:299;;;88257:4;-1:-1:-1;;;;;88257:20:0;;:22;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;88257:22:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;88257:22:0;;;;88209:299;;;88444:4;:20;88465:30;:8;88478:16;88465:30;:12;:30;:::i;:::-;88444:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;88444:52:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;88444:52:0;;;;88209:299;-1:-1:-1;;;;;;;;;;;;;;;;88559:31:0;;88591:7;88559:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;88559:40:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;88559:40:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;88559:40:0;:45;88551:65;;;;;-1:-1:-1;;;88551:65:0;;;;;;;;;;;;-1:-1:-1;;;88551:65:0;;;;;;;;;;;;;;;88693:17;88713:15;:13;:15::i;:::-;88693:35;-1:-1:-1;88751:23:0;88693:35;88765:8;88751:23;:13;:23;:::i;:::-;88739:35;87456:1355;-1:-1:-1;;;;;;;;;87456:1355:0:o;973:181::-;1031:7;1063:5;;;1087:6;;;;1079:46;;;;;-1:-1:-1;;;1079:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;85956:137;75096:42;;85956:137::o;62123:425::-;62224:14;;;;:22;;:14;:22;62220:321;;;62295:7;;62263:56;;62276:17;;62295:7;;;-1:-1:-1;;;;;62295:7:0;62304:14;62263:12;:56::i;:::-;62361:7;;62354:40;;;-1:-1:-1;;;62354:40:0;;62388:4;62354:40;;;;;;-1:-1:-1;;62361:7:0;;;-1:-1:-1;;;;;62361:7:0;;62354:25;;:40;;;;;;;;;;;;;;62361:7;62354:40;;;2:2:-1;;;;27:1;24;17:12;2:2;62354:40:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62354:40:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;62354:40:0;62438:10;;62416:7;;62354:40;;-1:-1:-1;62409:51:0;;62438:10;62416:7;;-1:-1:-1;;;;;62416:7:0;;;;62438:10;62354:40;62409:51;:28;:51;:::i;:::-;62487:10;;;62475:54;;;-1:-1:-1;;;62475:54:0;;;;;;;;;-1:-1:-1;;;;;62487:10:0;;;;62475:43;;:54;;;;;62487:10;;62475:54;;;;;;;62487:10;;62475:54;;;2:2:-1;;;;27:1;24;17:12;2:2;62475:54:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62475:54:0;;;;62220:321;62123:425;;:::o;26894:177::-;27004:58;;;-1:-1:-1;;;;;27004:58:0;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;27004:58:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;26977:86:0;;26997:5;;26977:19;:86::i;:::-;26894:177;;;:::o;64575:1537::-;-1:-1:-1;;;;;64704:17:0;;64696:26;;12:1:-1;9;2:12;64696:26:0;64791:12;;64765:42;;-1:-1:-1;;;;;64765:25:0;;;;64791:12;;64765:42;:25;:42;:::i;:::-;64844:12;;64818:48;;-1:-1:-1;;;;;64818:25:0;;;;64844:12;64858:7;64818:48;:25;:48;:::i;:::-;64924:7;;64879:21;;-1:-1:-1;;;;;64917:14:0;;;64924:7;;;;;64917:14;:40;;;;-1:-1:-1;64935:14:0;;;;:22;;:14;:22;64917:40;64913:1003;;;-1:-1:-1;;;;;64978:20:0;;56878:42;64978:20;64974:575;;;65025:16;;;65039:1;65025:16;;;;;;;;;;;;;;;109:14:-1;65025:16:0;88:42:-1;144:17;;-1:-1;65025:16:0;65018:23;;65070:5;65060:4;65065:1;65060:7;;;;;;;;;;;;;:15;-1:-1:-1;;;;;65060:15:0;;;-1:-1:-1;;;;;65060:15:0;;;;;65104:3;65094:4;65099:1;65094:7;;;;;;;;;;;;;:13;-1:-1:-1;;;;;65094:13:0;;;-1:-1:-1;;;;;65094:13:0;;;;;64974:575;;;65146:13;;-1:-1:-1;;;;;65137:22:0;;;65146:13;;65137:22;;:46;;-1:-1:-1;65172:11:0;;-1:-1:-1;;;;;65163:20:0;;;65172:11;;65163:20;65137:46;65134:415;;;65210:16;;;65224:1;65210:16;;;;;;;;;;;;;17:15:-1;;109:14;65210:16:0;88:42:-1;144:17;;-1:-1;65210:16:0;65203:23;;65255:5;65245:4;65250:1;65245:7;;;;;;;;;;;;;:15;-1:-1:-1;;;;;65245:15:0;;;-1:-1:-1;;;;;65245:15:0;;;;;56767:42;65279:4;65284:1;65279:7;;;;;;;;;;;;;:14;-1:-1:-1;;;;;65279:14:0;;;-1:-1:-1;;;;;65279:14:0;;;;;56878:42;65312:4;65317:1;65312:7;;;;;;;;;;;;;:21;-1:-1:-1;;;;;65312:21:0;;;-1:-1:-1;;;;;65312:21:0;;;;;65362:3;65352:4;65357:1;65352:7;;;;;;;65134:415;65411:16;;;65425:1;65411:16;;;;;;;;;;;;;17:15:-1;;109:14;65411:16:0;88:42:-1;144:17;;-1:-1;65411:16:0;65404:23;;65456:5;65446:4;65451:1;65446:7;;;;;;;;;;;;;:15;-1:-1:-1;;;;;65446:15:0;;;-1:-1:-1;;;;;65446:15:0;;;;;56878:42;65480:4;65485:1;65480:7;;;;;;;;;;;;;:21;-1:-1:-1;;;;;65480:21:0;;;-1:-1:-1;;;;;65480:21:0;;;;;65530:3;65520:4;65525:1;65520:7;;;;;;;;;;;;;:13;-1:-1:-1;;;;;65520:13:0;;;-1:-1:-1;;;;;65520:13:0;;;;;65134:415;64913:1003;;;-1:-1:-1;;;;;65586:13:0;;56767:42;65586:13;;:28;;-1:-1:-1;;;;;;65603:11:0;;56767:42;65603:11;65586:28;65582:321;;;65642:16;;;65656:1;65642:16;;;;;;;;;;;;;;;109:14:-1;65642:16:0;88:42:-1;144:17;;-1:-1;65642:16:0;65635:23;;65687:5;65677:4;65682:1;65677:7;;;;;;;;;;;;;:15;-1:-1:-1;;;;;65677:15:0;;;-1:-1:-1;;;;;65677:15:0;;;;;65721:3;65711:4;65716:1;65711:7;;;;;;;65582:321;65772:16;;;65786:1;65772:16;;;;;;;;;;;;;17:15:-1;;109:14;65772:16:0;88:42:-1;144:17;;-1:-1;65772:16:0;65765:23;;65817:5;65807:4;65812:1;65807:7;;;;;;;;;;;;;:15;-1:-1:-1;;;;;65807:15:0;;;-1:-1:-1;;;;;65807:15:0;;;;;56767:42;65841:4;65846:1;65841:7;;;;;;;;;;;;;:14;-1:-1:-1;;;;;65841:14:0;;;-1:-1:-1;;;;;65841:14:0;;;;;65884:3;65874:4;65879:1;65874:7;;;;;;;;;;;;;:13;-1:-1:-1;;;;;65874:13:0;;;-1:-1:-1;;;;;65874:13:0;;;;;65582:321;65944:12;;-1:-1:-1;;;;;65944:12:0;65928:54;65997:7;65944:12;66035:4;66062;66082:11;:3;66090:2;66082:11;:7;:11;:::i;:::-;65928:176;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;65928:176:0;-1:-1:-1;;;;;65928:176:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;65928:176:0;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;65928:176:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;65928:176:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;65928:176:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;15:2;7:11;;4:2;;;31:1;28;21:12;4:2;65928:176:0;;;;;;;;;;;;;19:11:-1;14:3;11:20;8:2;;;44:1;41;34:12;8:2;62:21;;;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;219:3;213:10;331:9;325:2;311:12;307:21;289:16;285:44;282:59;261:11;247:12;244:29;233:116;230:2;;;362:1;359;352:12;230:2;373:25;;-1:-1;65928:176:0;;421:4:-1;412:14;;;;65928:176:0;;;;;412:14:-1;65928:176:0;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;65928:176:0;;;;;;;;;;;;64575:1537;;;;:::o;60450:302::-;60564:10;;60514:15;;-1:-1:-1;;;;;60564:10:0;60550;:24;60542:48;;;;;-1:-1:-1;;;60542:48:0;;;;;;;;;;;;-1:-1:-1;;;60542:48:0;;;;;;;;;;;;;;;60609:4;;-1:-1:-1;;;;;60609:23:0;;;:4;;:23;;60601:40;;;;;-1:-1:-1;;;60601:40:0;;;;;;;;;;;;;;;-1:-1:-1;;;60601:40:0;;;;;;;;;;;;;;;60662:31;;;-1:-1:-1;;;60662:31:0;;60687:4;60662:31;;;;;;-1:-1:-1;;;;;60662:16:0;;;;;:31;;;;;;;;;;;;;;:16;:31;;;2:2:-1;;;;27:1;24;17:12;2:2;60662:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;60662:31:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;60662:31:0;60724:10;;60662:31;;-1:-1:-1;60704:40:0;;-1:-1:-1;;;;;60704:19:0;;;;60724:10;60662:31;60704:40;:19;:40;:::i;34773:313::-;34850:9;34861:4;34879:13;34894:18;;:::i;:::-;34916:20;34926:1;34929:6;34916:9;:20::i;:::-;34878:58;;-1:-1:-1;34878:58:0;-1:-1:-1;34958:18:0;34951:3;:25;;;;;;;;;34947:73;;-1:-1:-1;35001:3:0;-1:-1:-1;35006:1:0;;-1:-1:-1;34993:15:0;;34947:73;35040:18;35060:17;35069:7;35060:8;:17::i;:::-;35032:46;;;;;;34773:313;;;;;;:::o;63072:82::-;63116:30;63130:15;:13;:15::i;27553:622::-;27923:10;;;27922:62;;-1:-1:-1;27939:39:0;;;-1:-1:-1;;;27939:39:0;;27963:4;27939:39;;;;-1:-1:-1;;;;;27939:39:0;;;;;;;;;:15;;;;;;:39;;;;;;;;;;;;;;;:15;:39;;;2:2:-1;;;;27:1;24;17:12;2:2;27939:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;27939:39:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;27939:39:0;:44;27922:62;27914:152;;;;-1:-1:-1;;;27914:152:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28104:62;;;-1:-1:-1;;;;;28104:62:0;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;28104:62:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;28077:90:0;;28097:5;;28077:19;:90::i;3902:278::-;3988:7;4023:12;4016:5;4008:28;;;;-1:-1:-1;;;4008:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;4008:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4047:9;4063:1;4059;:5;;;;;;;3902:278;-1:-1:-1;;;;;3902:278:0:o;1876:192::-;1962:7;1998:12;1990:6;;;;1982:29;;;;-1:-1:-1;;;1982:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27:10:-1;;8:100;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;1982:29:0;-1:-1:-1;;;2034:5:0;;;1876:192::o;29199:761::-;29623:23;29649:69;29677:4;29649:69;;;;;;;;;;;;;;;;;29657:5;-1:-1:-1;;;;;29649:27:0;;;:69;;;;;:::i;:::-;29733:17;;29623:95;;-1:-1:-1;29733:21:0;29729:224;;29875:10;29864:30;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;29864:30:0;29856:85;;;;-1:-1:-1;;;29856:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34307:353;34376:9;34387:10;;:::i;:::-;34411:14;34427:19;34450:27;34458:1;:10;;;34470:6;34450:7;:27::i;:::-;34410:67;;-1:-1:-1;34410:67:0;-1:-1:-1;34500:18:0;34492:4;:26;;;;;;;;;34488:92;;-1:-1:-1;34549:18:0;;;;;;;;;-1:-1:-1;34549:18:0;;34543:4;;-1:-1:-1;34549:18:0;-1:-1:-1;34535:33:0;;34488:92;34620:31;;;;;;;;;;;;-1:-1:-1;;34620:31:0;;-1:-1:-1;34307:353:0;-1:-1:-1;;;;34307:353:0:o;39584:213::-;39766:12;32619:4;39766:23;;;39584:213::o;13022:196::-;13125:12;13157:53;13180:6;13188:4;13194:1;13197:12;13157:22;:53::i;:::-;13150:60;13022:196;-1:-1:-1;;;;13022:196:0:o;30505:343::-;30561:9;;30593:6;30589:69;;-1:-1:-1;30624:18:0;;-1:-1:-1;30624:18:0;30616:30;;30589:69;30679:5;;;30683:1;30679;:5;:1;30701:5;;;;;:10;30697:144;;-1:-1:-1;30736:26:0;;-1:-1:-1;30764:1:0;;-1:-1:-1;30728:38:0;;30697:144;30807:18;;-1:-1:-1;30827:1:0;-1:-1:-1;30799:30:0;;14399:979;14529:12;14562:18;14573:6;14562:10;:18::i;:::-;14554:60;;;;;-1:-1:-1;;;14554:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;14688:12;14702:23;14729:6;-1:-1:-1;;;;;14729:11:0;14749:8;14760:4;14729:36;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;14729:36:0;;;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;19;14:27;;;;67:4;61:11;56:16;;134:4;130:9;123:4;105:16;101:27;97:43;94:1;90:51;84:4;77:65;157:16;154:1;147:27;211:16;208:1;201:4;198:1;194:12;179:49;5:228;;14:27;32:4;27:9;;5:228;;14687:78:0;;;;14780:7;14776:595;;;14811:10;-1:-1:-1;14804:17:0;;-1:-1:-1;14804:17:0;14776:595;14925:17;;:21;14921:439;;15188:10;15182:17;15249:15;15236:10;15232:2;15228:19;15221:44;15136:148;15324:20;;-1:-1:-1;;;15324:20:0;;;;;;;;;;;;;;;;;15331:12;;15324:20;;;;;;;;;;;;;;;27:10:-1;;8:100;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;9907:619:0;9967:4;10435:20;;10278:66;10475:23;;;;;;:42;;-1:-1:-1;;10502:15:0;;;10467:51;-1:-1:-1;;9907:619:0:o;74825:14262::-;;;;;;;;;;;;;;:::o
Swarm Source
ipfs://e8ac17c2cf4541cd119378e41606f4066a4b9eb7d7108a1d733c85dac3cd848e
Loading...
Loading
Loading...
Loading
Net Worth in USD
$2,020.44
Net Worth in ETH
1.048253
Token Allocations
CUSDC
100.00%
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| ETH | 100.00% | $0.025323 | 79,786.1633 | $2,020.44 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.