More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 150 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Deleverage To Mi... | 13854107 | 1002 days ago | IN | 0 ETH | 0.05945387 | ||||
Leverage To Max | 13630633 | 1037 days ago | IN | 0 ETH | 0.12045102 | ||||
Harvest | 13630503 | 1037 days ago | IN | 0 ETH | 0.0857298 | ||||
Harvest | 13574241 | 1046 days ago | IN | 0 ETH | 0.0397594 | ||||
Harvest | 13534992 | 1052 days ago | IN | 0 ETH | 0.09216907 | ||||
Harvest | 13484836 | 1060 days ago | IN | 0 ETH | 0.03972225 | ||||
Harvest | 13440500 | 1067 days ago | IN | 0 ETH | 0.00847948 | ||||
Harvest | 13407554 | 1072 days ago | IN | 0 ETH | 0.01699088 | ||||
Harvest | 13388406 | 1075 days ago | IN | 0 ETH | 0.01327333 | ||||
Harvest | 13369311 | 1078 days ago | IN | 0 ETH | 0.11208211 | ||||
Harvest | 13350122 | 1081 days ago | IN | 0 ETH | 0.04941254 | ||||
Harvest | 13346688 | 1081 days ago | IN | 0 ETH | 0.03792093 | ||||
Harvest | 13330895 | 1084 days ago | IN | 0 ETH | 0.0147915 | ||||
Harvest | 13311734 | 1087 days ago | IN | 0 ETH | 0.0620266 | ||||
Harvest | 13275149 | 1093 days ago | IN | 0 ETH | 0.0277012 | ||||
Harvest | 13255707 | 1096 days ago | IN | 0 ETH | 0.0258946 | ||||
Harvest | 13236322 | 1099 days ago | IN | 0 ETH | 0.0409496 | ||||
Harvest | 13216917 | 1102 days ago | IN | 0 ETH | 0.0409496 | ||||
Harvest | 13197543 | 1105 days ago | IN | 0 ETH | 0.0566068 | ||||
Harvest | 13178194 | 1108 days ago | IN | 0 ETH | 0.06368139 | ||||
Leverage To Max | 13158720 | 1111 days ago | IN | 0 ETH | 0.04381068 | ||||
Harvest | 13158716 | 1111 days ago | IN | 0 ETH | 0.0818992 | ||||
Harvest | 13139035 | 1114 days ago | IN | 0 ETH | 0.05232911 | ||||
Leverage To Max | 13119628 | 1117 days ago | IN | 0 ETH | 0.02621741 | ||||
Harvest | 13119626 | 1117 days ago | IN | 0 ETH | 0.03805753 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
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:
StrategyCmpdWbtcV1
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-03-24 */ pragma solidity 0.6.12; /** * @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; } } /* * @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; } } /** * @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); } } } } /** * @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)}); } } 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; function balance() external view returns (uint256); function flashLoan(address, uint256, bytes calldata) external; function loanFee() external view returns (uint256); function loanFeeMax() external view returns (uint256); } 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; } 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); } 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; } 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 = true; address public mmToken = 0xa283aA7CfBB27EF0cfBcb2493dD9F4330E0fd304; address public masterChef = 0xf8873a6080e8dbF41ADa900498DE0951074af577; // 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) ); } } 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 ); } interface IChiToken { function freeFromUpTo(address from, uint256 value) external returns (uint256 freed); function balanceOf(address account) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); } interface IFlashLoanReceiver { /** * @dev execute caller's logic after borrowed tokens * @param _token the address of the reserve in which the flashloan is happening * @param _amount amount of the flashloan tokens * @param _loanFee flashloan fee of this transaction * @param _data the data from caller **/ function mushroomsFlashloan(address _token, uint256 _amount, uint256 _loanFee, bytes calldata _data) external; } // SPDX-License-Identifier: MIT contract StrategyCmpdWbtcV1 is StrategyBase, Exponential, IFlashLoanReceiver { address public constant comptroller = 0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B; address public constant lens = 0xd513d22422a3062Bd342Ae374b4b9c20E0a9a074; address public constant wbtc = 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599; address public constant comp = 0xc00e94Cb662C3520282E6f5717214004A7f26888; address public constant cwbtc = 0xccF4429DB6322D5C611ee964527D42E5d685DD6a; address public constant cether = 0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5; IChiToken public constant chi = IChiToken(0x0000000000004946c0e9F43F4Dee607b0eF1fA1c); // whether to use Mushrooms Flash Loan in leverage/deleverage address public mwbtc = 0xb06661A221Ab2Ec615531f9632D6Dc5D2984179A; bool public enableMushroomsFlashloan = true; // Require a 0.1 buffer between // market collateral factor and strategy's collateral factor // when leveraging uint256 public 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 public colFactorSyncBuffer = 50; uint256 colFactorSyncBufferMax = 1000; // 1 -> use flash loan to leverage bytes public constant flashLeverageFlag = abi.encodePacked("1"); // 2 -> use flash loan to deleverage bytes public constant flashDeleverageFlag = abi.encodePacked("2"); // Keeper bots // Maintain leverage within buffer mapping(address => bool) public keepers; event FlashLoanLeverage(uint256 _amount, uint256 _fee, bytes _data, string lender); event FlashLoanDeleverage(uint256 _amount, uint256 _fee, bytes _data, string lender); constructor( address _governance, address _strategist, address _controller, address _timelock ) public StrategyBase(wbtc, _governance, _strategist, _controller, _timelock) { // Enter cWBTC Market address[] memory ctokens = new address[](1); ctokens[0] = cwbtc; IComptroller(comptroller).enterMarkets(ctokens); } // **** Modifiers **** // modifier onlyKeepers { require( keepers[msg.sender] || msg.sender == address(this) || msg.sender == strategist || msg.sender == governance, "!keepers" ); _; } modifier onlyGovernanceAndStrategist { require(msg.sender == governance || msg.sender == strategist, "!governance"); _; } // **** Views **** // function getName() external override pure returns (string memory) { return "StrategyCmpdWbtcV1"; } function getSuppliedView() public view returns (uint256) { (, uint256 cTokenBal, , uint256 exchangeRate) = ICToken(cwbtc).getAccountSnapshot(address(this)); (, uint256 bal) = mulScalarTruncate(Exp({mantissa: exchangeRate}), cTokenBal); return bal; } function getBorrowedView() public view returns (uint256) { return ICToken(cwbtc).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(cwbtc); 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(cwbtc).balanceOfUnderlying(address(this)); } function getBorrowed() public returns (uint256) { return ICToken(cwbtc).borrowBalanceCurrent(address(this)); } function getBorrowable() public returns (uint256) { uint256 supplied = getSupplied(); uint256 borrowed = getBorrowed(); (, uint256 colFactor) = IComptroller(comptroller).markets(cwbtc); // 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 onlyGovernanceAndStrategist { keepers[_keeper] = true; } function removeKeeper(address _keeper) public onlyGovernanceAndStrategist { keepers[_keeper] = false; } function setColFactorLeverageBuffer(uint256 _colFactorLeverageBuffer) public onlyGovernanceAndStrategist { colFactorLeverageBuffer = _colFactorLeverageBuffer; } function setColFactorSyncBuffer(uint256 _colFactorSyncBuffer) public onlyGovernanceAndStrategist { colFactorSyncBuffer = _colFactorSyncBuffer; } function setEnableMushroomsFlashloan(bool _enableMushroomsFlashloan) public onlyGovernanceAndStrategist { enableMushroomsFlashloan = _enableMushroomsFlashloan; } function setMwbtc(address _mwbtc) public onlyGovernanceAndStrategist { mwbtc = _mwbtc; } // **** 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); } // only use flashloan when applicable, i.e., there is enough want to borrow function _mushroomsFlashloanApplicable(uint256 _gap) internal returns (bool){ return enableMushroomsFlashloan && mwbtc != address(0) && IERC20(want).balanceOf(mwbtc) > _gap; } // Leverages until we're supplying <x> amount // 1. Borrow out <X> WBTC // 2. Supply <X> WBTC function leverageUntil(uint256 _supplyAmount) public onlyKeepers { 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(); uint256 _gap = _supplyAmount.sub(supplied); if (_gap > 0 && _mushroomsFlashloanApplicable(_gap)){ IVault(mwbtc).flashLoan(address(this), _gap, flashLeverageFlag); } else{ while (supplied < _supplyAmount) { _borrowAndSupply = getBorrowable(); if (supplied.add(_borrowAndSupply) > _supplyAmount) { _borrowAndSupply = _supplyAmount.sub(supplied); } ICToken(cwbtc).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> WBTC // 2. Repay <x> WBTC 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(); uint256 _gap = supplied.sub(_supplyAmount); if (_gap > 0 && _mushroomsFlashloanApplicable(_gap)){ IVault(mwbtc).flashLoan(address(this), _gap, flashDeleverageFlag); } else { do { if (supplied.sub(_redeemAndRepay) < _supplyAmount) { _redeemAndRepay = supplied.sub(_supplyAmount); } require(ICToken(cwbtc).redeemUnderlying(_redeemAndRepay) == 0, "!redeemInDeleverageUntil"); IERC20(wbtc).safeApprove(cwbtc, 0); IERC20(wbtc).safeApprove(cwbtc, _redeemAndRepay); require(ICToken(cwbtc).repayBorrow(_redeemAndRepay) == 0, "!repay"); supplied = supplied.sub(_redeemAndRepay); } while (supplied > _supplyAmount); } } function _convertWantToBuyback(uint256 _lpAmount) internal override returns (address, uint256){ return (wbtc, _lpAmount); } function harvest() public override onlyBenevolent { address[] memory ctokens = new address[](1); ctokens[0] = cwbtc; 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(cwbtc, 0); IERC20(want).safeApprove(cwbtc, _want); require(ICToken(cwbtc).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(cwbtc).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); bool useFlashloan = false; // If the amount we need to free is > borrowed // Just free up all the borrowed amount if (borrowedToBeFree > borrowed) { useFlashloan = _mushroomsFlashloanApplicable(supplied.sub(getSuppliedUnleveraged())); this.deleverageToMin(); } else { // Otherwise just keep freeing up borrowed amounts until // we hit a safe number to redeem our underlying useFlashloan = _mushroomsFlashloanApplicable(borrowedToBeFree); this.deleverageUntil(supplied.sub(borrowedToBeFree)); } // Redeems underlying require(ICToken(cwbtc).redeemUnderlying(useFlashloan? _redeem.mul(IVault(mwbtc).loanFeeMax().sub(IVault(mwbtc).loanFee())).div(IVault(mwbtc).loanFeeMax()) : _redeem) == 0, "!redeemInWithdrawSome"); // -- 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(cwbtc != address(_asset), "!cToken"); balance = _withdrawNonWantAsset(_asset); } // **** Flash Loan related **** // // callback hook by Mushrooms vault function mushroomsFlashloan(address _token, uint256 _amount, uint256 _loanFee, bytes calldata _data) external override { require(enableMushroomsFlashloan && mwbtc != address(0), '!noFlashLoan'); require(_token == want, '!mismatchFlashToken'); require(balanceOfWant() >= _amount, '!invalidFlashAmount'); uint256 total = _amount.add(_loanFee); bytes memory _dataCopy = _data; chi.approve(address(mwbtc), 0); chi.approve(address(mwbtc), uint256(-1)); // 1 -> use flash loan to leverage if (_dataCopy[0] == 0x31){ deposit(); require(getBorrowable() >= total, '!borrowableFlashRepay'); require(ICToken(cwbtc).borrow(total) == 0, "!borrowFlashLeverage"); emit FlashLoanLeverage(_amount, _loanFee, _data, ERC20(mwbtc).name()); } // 2 -> use flash loan to deleverage else if(_dataCopy[0] == 0x32){ IERC20(wbtc).safeApprove(cwbtc, 0); IERC20(wbtc).safeApprove(cwbtc, _amount); require(ICToken(cwbtc).repayBorrow(_amount) == 0, "!repayFlashDeleverage"); // Since we're only leveraging on 1 asset: redeemable = borrowable require(getBorrowable() >= total, '!borrowableFlashRepay'); require(ICToken(cwbtc).redeemUnderlying(total) == 0, "!redeemFlashDeleverage"); emit FlashLoanDeleverage(_amount, _loanFee, _data, ERC20(mwbtc).name()); } require(balanceOfWant() >= total, '!deficitFlashRepay'); IERC20(want).transfer(mwbtc, total); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_fee","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"},{"indexed":false,"internalType":"string","name":"lender","type":"string"}],"name":"FlashLoanDeleverage","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_fee","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"},{"indexed":false,"internalType":"string","name":"lender","type":"string"}],"name":"FlashLoanLeverage","type":"event"},{"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":"chi","outputs":[{"internalType":"contract IChiToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"colFactorLeverageBuffer","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"colFactorSyncBuffer","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"cwbtc","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":[],"name":"enableMushroomsFlashloan","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"flashDeleverageFlag","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flashLeverageFlag","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","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":[{"internalType":"address","name":"","type":"address"}],"name":"keepers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_loanFee","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"mushroomsFlashloan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mwbtc","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":"bool","name":"_enableMushroomsFlashloan","type":"bool"}],"name":"setEnableMushroomsFlashloan","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":"address","name":"_mwbtc","type":"address"}],"name":"setMwbtc","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":"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":"wbtc","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
6080604052617530600055608c6001908155603c6002556003805474a283aa7cfbb27ef0cfbcb2493dd9f4330e0fd30400610100600160a81b031960ff1990921690931716919091179055600480546001600160a01b031990811673f8873a6080e8dbf41ada900498de0951074af57717909155600680548216732260fac5e5542a773aa44fbcfedf7c193bc2c59917905560078054821673eb4c2781e4eba804ce9a9803c67d0893436bb27d179055600c80548216737a250d5630b4cf539739df2c5dacb4c659f2488d179055600d805460ff60a01b19921673b06661a221ab2ec615531f9632d6dc5d2984179a1791909116600160a01b1790556064600e556103e8600f81905560326010556011553480156200011d57600080fd5b50604051620055e6380380620055e6833981810160405260808110156200014357600080fd5b5080516020820151604083015160609093015191929091732260fac5e5542a773aa44fbcfedf7c193bc2c599848484846001600160a01b0384166200018757600080fd5b6001600160a01b0383166200019b57600080fd5b6001600160a01b038216620001af57600080fd5b6001600160a01b038116620001c357600080fd5b600580546001600160a01b03199081166001600160a01b039788161790915560088054821695871695909517909455600a8054851693861693909317909255600980548416918516919091179055600b805490921692169190911790556040805160018082528183019092526060916020808301908036833701905050905073ccf4429db6322d5c611ee964527d42e5d685dd6a816000815181106200026557fe5b6001600160a01b03909216602092830291909101820152604051631853304760e31b815260048101828152835160248301528351733d9819210a31b4961b30ef54be2aed79b9c9cd3b9363c2998238938693928392604490920191858101910280838360005b83811015620002e5578181015183820152602001620002cb565b5050505090500192505050600060405180830381600087803b1580156200030b57600080fd5b505af115801562000320573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156200034a57600080fd5b81019080805160405193929190846401000000008211156200036b57600080fd5b9083019060208201858111156200038157600080fd5b82518660208202830111640100000000821117156200039f57600080fd5b82525081516020918201928201910280838360005b83811015620003ce578181015183820152602001620003b4565b505050509050016040525050505050505050506151f580620003f16000396000f3fe6080604052600436106104735760003560e01c8063654028821161024a578063ab033ea911610139578063cc32d176116100b6578063eb514af91161007a578063eb514af914610e5a578063f4aa3a8d14610e84578063f53f135014610eae578063f77c479114610ec3578063fff6cae914610ed857610473565b8063cc32d17614610d6f578063cd04f09514610d84578063ce7079ba14610e1b578063d0e30db014610e30578063d33219b414610e4557610473565b8063b9e37489116100fd578063b9e3748914610cca578063bdacb30314610cdf578063c1a3d44c14610d12578063c7b9d53014610d27578063c92aecc414610d5a57610473565b8063ab033ea914610c25578063ac41ceb314610c58578063ae104b2f14610c6d578063b01db4ec14610ca0578063b635b8ae14610cb557610473565b8063857a52b8116101c75780639c4b81631161018b5780639c4b816314610b895780639eb52f6114610b9e578063a1e003e414610bb3578063a2d9f4dc14610bdd578063a890dd9014610c1057610473565b8063857a52b814610aeb5780638778878214610b0057806392eefe9b14610b155780639324f4fe14610b485780639a9b567d14610b5d57610473565b806377da835a1161020e57806377da835a14610a8257806377e741c714610a975780637cc79113146105b95780638081e1cf14610ac1578063853828b614610ad657610473565b806365402882146109ed57806370897b2314610a19578063722713f714610a43578063726d1f2e14610a585780637396a62614610a6d57610473565b8063302ab80d116103665780634a183ffc116102e35780635aa6e675116102a75780635aa6e675146109845780635bfb92ce146109995780635c208490146109ae5780635eefb092146109c35780635fe3b567146109d857610473565b80634a183ffc146108e85780634df268b5146108fd57806351cff8d914610912578063575a86b21461094557806359bca6791461095a57610473565b80633cdc53891161032a5780633cdc5389146108615780633fc8cef3146108765780634032b72b1461088b578063463289ed146108be5780634641257d146108d357610473565b8063302ab80d146107c55780633355104d146107ef5780633865cc97146108045780633bbd64bc146108195780633c5dae941461084c57610473565b806314f7910c116103f45780631f1fcd51116103b85780631f1fcd51146107475780631fe4a6861461075c5780632a99417d146107715780632bfc9c23146107865780632e1a7d4d1461079b57610473565b806314f7910c1461062b57806315ac03fd14610640578063160d0da51461065557806317d7de7c1461067e5780631cff79cd1461069357610473565b8063115880861161043b57806311588086146105a457806313bd4b95146105b957806314a1fe02146105b957806314ae9f2e146105ce57806314e6ac091461060157610473565b806301a4b1691461047857806305166eff146105025780630ea8b3bf14610537578063109d0af81461055e578063112666b71461058f575b600080fd5b34801561048457600080fd5b5061048d610eed565b6040805160208082528351818301528351919283929083019185019080838360005b838110156104c75781810151838201526020016104af565b50505050905090810190601f1680156104f45780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561050e57600080fd5b506105356004803603602081101561052557600080fd5b50356001600160a01b0316610f10565b005b34801561054357600080fd5b5061054c610f85565b60408051918252519081900360200190f35b34801561056a57600080fd5b50610573610fc0565b604080516001600160a01b039092168252519081900360200190f35b34801561059b57600080fd5b50610573610fd8565b3480156105b057600080fd5b5061054c610ff0565b3480156105c557600080fd5b5061054c611013565b3480156105da57600080fd5b50610535600480360360208110156105f157600080fd5b50356001600160a01b031661101a565b34801561060d57600080fd5b506105356004803603602081101561062457600080fd5b503561109d565b34801561063757600080fd5b506105736110ed565b34801561064c57600080fd5b506105736110ff565b34801561066157600080fd5b5061066a611117565b604080519115158252519081900360200190f35b34801561068a57600080fd5b5061048d611120565b61048d600480360360408110156106a957600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156106d357600080fd5b8201836020820111156106e557600080fd5b803590602001918460018302840111600160201b8311171561070657600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061114c945050505050565b34801561075357600080fd5b5061057361122f565b34801561076857600080fd5b5061057361123e565b34801561077d57600080fd5b5061054c61124d565b34801561079257600080fd5b5061054c611282565b3480156107a757600080fd5b50610535600480360360208110156107be57600080fd5b50356112c8565b3480156107d157600080fd5b50610535600480360360208110156107e857600080fd5b5035611634565b3480156107fb57600080fd5b5061066a61169b565b34801561081057600080fd5b5061054c6116ab565b34801561082557600080fd5b5061066a6004803603602081101561083c57600080fd5b50356001600160a01b03166116b1565b34801561085857600080fd5b5061054c6116c6565b34801561086d57600080fd5b50610573611702565b34801561088257600080fd5b5061057361171a565b34801561089757600080fd5b50610535600480360360208110156108ae57600080fd5b50356001600160a01b0316611732565b3480156108ca57600080fd5b5061054c6117b8565b3480156108df57600080fd5b5061053561184f565b3480156108f457600080fd5b50610573611bac565b34801561090957600080fd5b5061054c611bbb565b34801561091e57600080fd5b5061054c6004803603602081101561093557600080fd5b50356001600160a01b0316611bc1565b34801561095157600080fd5b50610573611c28565b34801561096657600080fd5b506105356004803603602081101561097d57600080fd5b5035611c37565b34801561099057600080fd5b50610573611c9e565b3480156109a557600080fd5b5061054c611cad565b3480156109ba57600080fd5b5061054c611ce5565b3480156109cf57600080fd5b5061054c611d66565b3480156109e457600080fd5b50610573611dc9565b3480156109f957600080fd5b5061053560048036036020811015610a1057600080fd5b50351515611de1565b348015610a2557600080fd5b5061053560048036036020811015610a3c57600080fd5b5035611e61565b348015610a4f57600080fd5b5061054c611eb1565b348015610a6457600080fd5b5061048d611ed1565b348015610a7957600080fd5b5061054c611ef4565b348015610a8e57600080fd5b5061054c611f29565b348015610aa357600080fd5b5061053560048036036020811015610aba57600080fd5b5035611fe8565b348015610acd57600080fd5b5061054c612038565b348015610ae257600080fd5b5061054c612088565b348015610af757600080fd5b5061057361223a565b348015610b0c57600080fd5b5061054c612252565b348015610b2157600080fd5b5061053560048036036020811015610b3857600080fd5b50356001600160a01b0316612258565b348015610b5457600080fd5b506105736122c5565b348015610b6957600080fd5b5061053560048036036020811015610b8057600080fd5b503515156122d4565b348015610b9557600080fd5b5061054c612334565b348015610baa57600080fd5b5061054c61234b565b348015610bbf57600080fd5b5061054c60048036036020811015610bd657600080fd5b5035612420565b348015610be957600080fd5b5061053560048036036020811015610c0057600080fd5b50356001600160a01b031661244c565b348015610c1c57600080fd5b506105736124bb565b348015610c3157600080fd5b5061053560048036036020811015610c4857600080fd5b50356001600160a01b03166124cf565b348015610c6457600080fd5b5061053561253e565b348015610c7957600080fd5b5061053560048036036020811015610c9057600080fd5b50356001600160a01b0316612564565b348015610cac57600080fd5b5061054c6125e8565b348015610cc157600080fd5b5061054c6126a8565b348015610cd657600080fd5b506105736126ae565b348015610ceb57600080fd5b5061053560048036036020811015610d0257600080fd5b50356001600160a01b03166126bd565b348015610d1e57600080fd5b5061054c61272a565b348015610d3357600080fd5b5061053560048036036020811015610d4a57600080fd5b50356001600160a01b0316612775565b348015610d6657600080fd5b506105736127e4565b348015610d7b57600080fd5b5061054c6127f6565b348015610d9057600080fd5b5061053560048036036080811015610da757600080fd5b6001600160a01b038235169160208101359160408201359190810190608081016060820135600160201b811115610ddd57600080fd5b820183602082011115610def57600080fd5b803590602001918460018302840111600160201b83111715610e1057600080fd5b5090925090506127fc565b348015610e2757600080fd5b5061057361332f565b348015610e3c57600080fd5b5061053561333e565b348015610e5157600080fd5b506105736134c8565b348015610e6657600080fd5b5061053560048036036020811015610e7d57600080fd5b50356134d7565b348015610e9057600080fd5b5061053560048036036020811015610ea757600080fd5b5035613910565b348015610eba57600080fd5b50610535613c0f565b348015610ecf57600080fd5b50610573613c24565b348015610ee457600080fd5b5061066a613c33565b60408051601960f91b602082015281518082036001018152602190910190915281565b6008546001600160a01b03163314610f5d576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600380546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b600080610f906116c6565b90506000610fb86ec097ce7bc90715b34b9f1000000000670de0b6b3a7640000849003613c8c565b925050505b90565b73c00e94cb662c3520282e6f5717214004a7f2688881565b73d513d22422a3062bd342ae374b4b9c20e0a9a07481565b600080610ffb611f29565b90506000611007611d66565b9050610fb88282613cd5565b620186a081565b6008546001600160a01b031633148061103d5750600a546001600160a01b031633145b61107c576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b6001600160a01b03166000908152601260205260409020805460ff19169055565b600b546001600160a01b031633146110e8576040805162461bcd60e51b81526020600482015260096024820152682174696d656c6f636b60b81b604482015290519081900360640190fd5b600255565b60008051602061511f83398151915281565b734ddc2d193948926d02f9b1fe9e1daa0718270ed581565b60035460ff1681565b6040805180820190915260128152715374726174656779436d706457627463563160701b602082015290565b600b546060906001600160a01b0316331461119a576040805162461bcd60e51b81526020600482015260096024820152682174696d656c6f636b60b81b604482015290519081900360640190fd5b6001600160a01b0383166111df576040805162461bcd60e51b8152602060048201526007602482015266085d185c99d95d60ca1b604482015290519081900360640190fd5b600080835160208501866113885a03f43d6040519250601f19601f6020830101168301604052808352806000602085013e81156001811461121f57611226565b8160208501fd5b50505092915050565b6005546001600160a01b031681565b600a546001600160a01b031681565b600080611258611ce5565b90506000611264612038565b9050610fb88261127c83670de0b6b3a7640000613d17565b90613c8c565b60008061128d6116c6565b90506112c28161127c600f5461127c68056bc75e2d631000006112bc60b6600e54613d1790919063ffffffff16565b90613d17565b91505090565b6009546001600160a01b03163314611315576040805162461bcd60e51b815260206004820152600b60248201526a10b1b7b73a3937b63632b960a91b604482015290519081900360640190fd5b600554604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561136057600080fd5b505afa158015611374573d6000803e3d6000fd5b505050506040513d602081101561138a57600080fd5b50519050818110156113b7576113a86113a38383613cd5565b613d70565b91506113b482826141b9565b91505b60006113d5620186a061127c60025486613d1790919063ffffffff16565b905060006113f5620186a061127c60015487613d1790919063ffffffff16565b60035490915060ff161515600114156114325760008061141d61141885856141b9565b614213565b9150915061142b828261422b565b505061153c565b60095460408051638d8f1e6760e01b815290516114b7926001600160a01b031691638d8f1e67916004808301926020929190829003018186803b15801561147857600080fd5b505afa15801561148c573d6000803e3d6000fd5b505050506040513d60208110156114a257600080fd5b50516005546001600160a01b03169084614361565b600954604080516361d027b360e01b8152905161153c926001600160a01b0316916361d027b3916004808301926020929190829003018186803b1580156114fd57600080fd5b505afa158015611511573d6000803e3d6000fd5b505050506040513d602081101561152757600080fd5b50516005546001600160a01b03169083614361565b60095460055460408051632988bb9f60e21b81526001600160a01b0392831660048201529051600093929092169163a622ee7c91602480820192602092909190829003018186803b15801561159057600080fd5b505afa1580156115a4573d6000803e3d6000fd5b505050506040513d60208110156115ba57600080fd5b505190506001600160a01b038116611602576040805162461bcd60e51b8152602060048201526006602482015265085d985d5b1d60d21b604482015290519081900360640190fd5b61162d8161161a846116148988613cd5565b90613cd5565b6005546001600160a01b03169190614361565b5050505050565b6008546001600160a01b03163314806116575750600a546001600160a01b031633145b611696576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600e55565b600d54600160a01b900460ff1681565b60105481565b60126020526000908152604090205460ff1681565b6000806116d16117b8565b90506000610fb86116fb600f5461127c670de0b6b3a7640000600e54613d1790919063ffffffff16565b8390613cd5565b732260fac5e5542a773aa44fbcfedf7c193bc2c59981565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6008546001600160a01b03163314806117555750600a546001600160a01b031633145b611794576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b6001600160a01b03166000908152601260205260409020805460ff19166001179055565b60408051638e8f294b60e01b815260008051602061511f833981519152600482015281516000928392733d9819210a31b4961b30ef54be2aed79b9c9cd3b92638e8f294b92602480840193919291829003018186803b15801561181a57600080fd5b505afa15801561182e573d6000803e3d6000fd5b505050506040513d604081101561184457600080fd5b506020015191505090565b3332148061186757506008546001600160a01b031633145b8061187c5750600a546001600160a01b031633145b61188557600080fd5b6040805160018082528183019092526060916020808301908036833701905050905060008051602061511f833981519152816000815181106118c357fe5b6001600160a01b039092166020928302919091018201526040805162e1ed9760e51b8152306004820181815260248301938452855160448401528551733d9819210a31b4961b30ef54be2aed79b9c9cd3b95631c3db2e0959394889492606490910191858101910280838360005b83811015611949578181015183820152602001611931565b505050509050019350505050600060405180830381600087803b15801561196f57600080fd5b505af1158015611983573d6000803e3d6000fd5b5050604080516370a0823160e01b815230600482015290516000935073c00e94cb662c3520282e6f5717214004a7f2688892506370a0823191602480820192602092909190829003018186803b1580156119dc57600080fd5b505afa1580156119f0573d6000803e3d6000fd5b505050506040513d6020811015611a0657600080fd5b505190508015611a3c57600554611a3c9073c00e94cb662c3520282e6f5717214004a7f26888906001600160a01b0316836143b8565b600554604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015611a8757600080fd5b505afa158015611a9b573d6000803e3d6000fd5b505050506040513d6020811015611ab157600080fd5b50516000805491925090611acf90620186a09061127c908590613d17565b60035490915060ff1615156001148015611ae95750600081115b15611b0957600554611b04906001600160a01b03168261422b565b611b98565b8115611b9857600954604080516361d027b360e01b81529051611b98926001600160a01b0316916361d027b3916004808301926020929190829003018186803b158015611b5557600080fd5b505afa158015611b69573d6000803e3d6000fd5b505050506040513d6020811015611b7f57600080fd5b505160005461161a90620186a09061127c908790613d17565b8115611ba657611ba661333e565b50505050565b6007546001600160a01b031681565b600e5481565b600060008051602061511f8339815191526001600160a01b0383161415611c19576040805162461bcd60e51b815260206004820152600760248201526610b1aa37b5b2b760c91b604482015290519081900360640190fd5b611c228261499b565b92915050565b6004546001600160a01b031681565b6008546001600160a01b0316331480611c5a5750600a546001600160a01b031633145b611c99576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b601055565b6008546001600160a01b031681565b600080611cb8611ce5565b90506000611cc4612038565b9050610fb8611cd38383613cd5565b61127c84670de0b6b3a7640000613d17565b60408051633af9e66960e01b8152306004820152905160009160008051602061511f83398151915291633af9e6699160248082019260209290919082900301818787803b158015611d3557600080fd5b505af1158015611d49573d6000803e3d6000fd5b505050506040513d6020811015611d5f57600080fd5b5051905090565b604080516395dd919360e01b8152306004820152905160009160008051602061511f833981519152916395dd919391602480820192602092909190829003018186803b158015611db557600080fd5b505afa158015611d49573d6000803e3d6000fd5b733d9819210a31b4961b30ef54be2aed79b9c9cd3b81565b6008546001600160a01b0316331480611e045750600a546001600160a01b031633145b611e43576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600d8054911515600160a01b0260ff60a01b19909216919091179055565b600b546001600160a01b03163314611eac576040805162461bcd60e51b81526020600482015260096024820152682174696d656c6f636b60b81b604482015290519081900360640190fd5b600055565b6000611ecc611ebe610ff0565b611ec661272a565b906141b9565b905090565b60408051603160f81b602082015281518082036001018152602190910190915281565b600080611eff6117b8565b90506000610fb86116fb60115461127c670de0b6b3a7640000601054613d1790919063ffffffff16565b600080600060008051602061511f8339815191526001600160a01b031663c37f68e2306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060806040518083038186803b158015611f8957600080fd5b505afa158015611f9d573d6000803e3d6000fd5b505050506040513d6080811015611fb357600080fd5b50602080820151606090920151604080519283019052808252919350909150600090611fdf9084614ac6565b94505050505090565b600b546001600160a01b03163314612033576040805162461bcd60e51b81526020600482015260096024820152682174696d656c6f636b60b81b604482015290519081900360640190fd5b600155565b604080516305eff7ef60e21b8152306004820152905160009160008051602061511f833981519152916317bfdfbc9160248082019260209290919082900301818787803b158015611d3557600080fd5b6009546000906001600160a01b031633146120d8576040805162461bcd60e51b815260206004820152600b60248201526a10b1b7b73a3937b63632b960a91b604482015290519081900360640190fd5b6120e0614b1a565b600554604080516370a0823160e01b815230600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b15801561212b57600080fd5b505afa15801561213f573d6000803e3d6000fd5b505050506040513d602081101561215557600080fd5b505160095460055460408051632988bb9f60e21b81526001600160a01b0392831660048201529051939450600093919092169163a622ee7c916024808301926020929190829003018186803b1580156121ad57600080fd5b505afa1580156121c1573d6000803e3d6000fd5b505050506040513d60208110156121d757600080fd5b505190506001600160a01b03811661221f576040805162461bcd60e51b8152602060048201526006602482015265085d985d5b1d60d21b604482015290519081900360640190fd5b600554612236906001600160a01b03168284614361565b5090565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b60005481565b600b546001600160a01b031633146122a3576040805162461bcd60e51b81526020600482015260096024820152682174696d656c6f636b60b81b604482015290519081900360640190fd5b600980546001600160a01b0319166001600160a01b0392909216919091179055565b600d546001600160a01b031681565b6008546001600160a01b03163314612321576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b6003805460ff1916911515919091179055565b60008061233f611ce5565b90506000611007612038565b600080612356611ce5565b90506000612362612038565b60408051638e8f294b60e01b815260008051602061511f83398151915260048201528151929350600092733d9819210a31b4961b30ef54be2aed79b9c9cd3b92638e8f294b9260248082019391829003018186803b1580156123c357600080fd5b505afa1580156123d7573d6000803e3d6000fd5b505050506040513d60408110156123ed57600080fd5b5060200151905061241861271061127c61270f6112bc86611614670de0b6b3a7640000858b8a613d17565b935050505090565b60008061242b610f85565b9050612443670de0b6b3a764000061127c8584613d17565b9150505b919050565b6008546001600160a01b03163314612499576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b60035461010090046001600160a01b031681565b6008546001600160a01b0316331461251c576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600880546001600160a01b0319166001600160a01b0392909216919091179055565b6000612548612334565b9050600061255582612420565b905061256081613910565b5050565b6008546001600160a01b03163314806125875750600a546001600160a01b031633145b6125c6576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b60408051631ea6374160e01b815273c00e94cb662c3520282e6f5717214004a7f268886004820152733d9819210a31b4961b30ef54be2aed79b9c9cd3b60248201523060448201529051600091829173d513d22422a3062bd342ae374b4b9c20e0a9a07491631ea6374191606480830192608092919082900301818787803b15801561267357600080fd5b505af1158015612687573d6000803e3d6000fd5b505050506040513d608081101561269d57600080fd5b506060015191505090565b60025481565b600c546001600160a01b031681565b600b546001600160a01b03163314612708576040805162461bcd60e51b81526020600482015260096024820152682174696d656c6f636b60b81b604482015290519081900360640190fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b600554604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015611db557600080fd5b6008546001600160a01b031633146127c2576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b6d4946c0e9f43f4dee607b0ef1fa1c81565b60015481565b600d54600160a01b900460ff16801561281f5750600d546001600160a01b031615155b61285f576040805162461bcd60e51b815260206004820152600c60248201526b10b737a33630b9b42637b0b760a11b604482015290519081900360640190fd5b6005546001600160a01b038681169116146128b7576040805162461bcd60e51b815260206004820152601360248201527210b6b4b9b6b0ba31b4233630b9b42a37b5b2b760691b604482015290519081900360640190fd5b836128c061272a565b1015612909576040805162461bcd60e51b8152602060048201526013602482015272085a5b9d985b1a59119b185cda105b5bdd5b9d606a1b604482015290519081900360640190fd5b600061291585856141b9565b9050606083838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250600d546040805163095ea7b360e01b81526001600160a01b03909216600483015260248201839052519596506d4946c0e9f43f4dee607b0ef1fa1c9563095ea7b3955060448083019550602094509092918390030190829087803b1580156129b257600080fd5b505af11580156129c6573d6000803e3d6000fd5b505050506040513d60208110156129dc57600080fd5b5050600d546040805163095ea7b360e01b81526001600160a01b0390921660048301526000196024830152516d4946c0e9f43f4dee607b0ef1fa1c9163095ea7b39160448083019260209291908290030181600087803b158015612a3f57600080fd5b505af1158015612a53573d6000803e3d6000fd5b505050506040513d6020811015612a6957600080fd5b505080518190600090612a7857fe5b6020910101516001600160f81b031916603160f81b1415612dd057612a9b61333e565b81612aa461234b565b1015612aef576040805162461bcd60e51b815260206004820152601560248201527421626f72726f7761626c65466c617368526570617960581b604482015290519081900360640190fd5b60008051602061511f8339815191526001600160a01b031663c5ebeaec836040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015612b4357600080fd5b505af1158015612b57573d6000803e3d6000fd5b505050506040513d6020811015612b6d57600080fd5b505115612bb8576040805162461bcd60e51b815260206004820152601460248201527321626f72726f77466c6173684c6576657261676560601b604482015290519081900360640190fd5b7f160548f48e39cd1b13c1762e9aeb707b3ba179f6e17ddc3a88e8de040ddf3a7486868686600d60009054906101000a90046001600160a01b03166001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b158015612c2b57600080fd5b505afa158015612c3f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015612c6857600080fd5b8101908080516040519392919084600160201b821115612c8757600080fd5b908301906020820185811115612c9c57600080fd5b8251600160201b811182820188101715612cb557600080fd5b82525081516020918201929091019080838360005b83811015612ce2578181015183820152602001612cca565b50505050905090810190601f168015612d0f5780820380516001836020036101000a031916815260200191505b5060405250505060405180868152602001858152602001806020018060200183810383528686828181526020019250808284376000838201819052601f909101601f191690920185810384528651815286516020918201939188019250908190849084905b83811015612d8c578181015183820152602001612d74565b50505050905090810190601f168015612db95780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390a1613250565b80600081518110612ddd57fe5b6020910101516001600160f81b031916601960f91b141561325057612e26732260fac5e5542a773aa44fbcfedf7c193bc2c59960008051602061511f8339815191526000614b25565b612e53732260fac5e5542a773aa44fbcfedf7c193bc2c59960008051602061511f83398151915288614b25565b60008051602061511f8339815191526001600160a01b0316630e752702876040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015612ea757600080fd5b505af1158015612ebb573d6000803e3d6000fd5b505050506040513d6020811015612ed157600080fd5b505115612f1d576040805162461bcd60e51b8152602060048201526015602482015274217265706179466c61736844656c6576657261676560581b604482015290519081900360640190fd5b81612f2661234b565b1015612f71576040805162461bcd60e51b815260206004820152601560248201527421626f72726f7761626c65466c617368526570617960581b604482015290519081900360640190fd5b60008051602061511f8339815191526001600160a01b031663852a12e3836040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015612fc557600080fd5b505af1158015612fd9573d6000803e3d6000fd5b505050506040513d6020811015612fef57600080fd5b50511561303c576040805162461bcd60e51b81526020600482015260166024820152752172656465656d466c61736844656c6576657261676560501b604482015290519081900360640190fd5b7fa6bedcf9169bb8eda4b6e84a0872589b7e6af9d164a399143c85371b0876536186868686600d60009054906101000a90046001600160a01b03166001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156130af57600080fd5b505afa1580156130c3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156130ec57600080fd5b8101908080516040519392919084600160201b82111561310b57600080fd5b90830190602082018581111561312057600080fd5b8251600160201b81118282018810171561313957600080fd5b82525081516020918201929091019080838360005b8381101561316657818101518382015260200161314e565b50505050905090810190601f1680156131935780820380516001836020036101000a031916815260200191505b5060405250505060405180868152602001858152602001806020018060200183810383528686828181526020019250808284376000838201819052601f909101601f191690920185810384528651815286516020918201939188019250908190849084905b838110156132105781810151838201526020016131f8565b50505050905090810190601f16801561323d5780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390a15b8161325961272a565b10156132a1576040805162461bcd60e51b81526020600482015260126024820152712164656669636974466c617368526570617960701b604482015290519081900360640190fd5b600554600d546040805163a9059cbb60e01b81526001600160a01b039283166004820152602481018690529051919092169163a9059cbb9160448083019260209291908290030181600087803b1580156132fa57600080fd5b505af115801561330e573d6000803e3d6000fd5b505050506040513d602081101561332457600080fd5b505050505050505050565b6006546001600160a01b031681565b600554604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561338957600080fd5b505afa15801561339d573d6000803e3d6000fd5b505050506040513d60208110156133b357600080fd5b5051905080156134c5576005546133e3906001600160a01b031660008051602061511f8339815191526000614b25565b600554613408906001600160a01b031660008051602061511f83398151915283614b25565b60008051602061511f8339815191526001600160a01b031663a0712d68826040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b15801561345c57600080fd5b505af1158015613470573d6000803e3d6000fd5b505050506040513d602081101561348657600080fd5b5051156134c5576040805162461bcd60e51b81526020600482015260086024820152670859195c1bdcda5d60c21b604482015290519081900360640190fd5b50565b600b546001600160a01b031681565b3360009081526012602052604090205460ff16806134f457503330145b806135095750600a546001600160a01b031633145b8061351e57506008546001600160a01b031633145b61355a576040805162461bcd60e51b8152602060048201526008602482015267216b65657065727360c01b604482015290519081900360640190fd5b6000613564612334565b90506000613570611ce5565b90508183101580156135825750808311155b6135c1576040805162461bcd60e51b815260206004820152600b60248201526a2164656c6576657261676560a81b604482015290519081900360640190fd5b60006135cb61234b565b905060006135d98386613cd5565b90506000811180156135ef57506135ef81614c38565b156136f057600d5460408051601960f91b60208083019190915282518083036001018152602183019384905263701195a160e11b9093523060258301818152604584018790526060606585019081528551608586015285516001600160a01b039097169663e0232b42969395899560a5909101919085019080838360005b8381101561368557818101518382015260200161366d565b50505050905090810190601f1680156136b25780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156136d357600080fd5b505af11580156136e7573d6000803e3d6000fd5b5050505061162d565b846136fb8484613cd5565b101561370e5761370b8386613cd5565b91505b60008051602061511f8339815191526001600160a01b031663852a12e3836040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b15801561376257600080fd5b505af1158015613776573d6000803e3d6000fd5b505050506040513d602081101561378c57600080fd5b5051156137e0576040805162461bcd60e51b815260206004820152601860248201527f2172656465656d496e44656c65766572616765556e74696c0000000000000000604482015290519081900360640190fd5b61380e732260fac5e5542a773aa44fbcfedf7c193bc2c59960008051602061511f8339815191526000614b25565b61383b732260fac5e5542a773aa44fbcfedf7c193bc2c59960008051602061511f83398151915284614b25565b60008051602061511f8339815191526001600160a01b0316630e752702836040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b15801561388f57600080fd5b505af11580156138a3573d6000803e3d6000fd5b505050506040513d60208110156138b957600080fd5b5051156138f6576040805162461bcd60e51b815260206004820152600660248201526521726570617960d01b604482015290519081900360640190fd5b6139008383613cd5565b92508483116136f0575050505050565b3360009081526012602052604090205460ff168061392d57503330145b806139425750600a546001600160a01b031633145b8061395757506008546001600160a01b031633145b613993576040805162461bcd60e51b8152602060048201526008602482015267216b65657065727360c01b604482015290519081900360640190fd5b600061399d610f85565b905060006139a9612334565b90508083101580156139d057506139cc670de0b6b3a764000061127c8385613d17565b8311155b613a0d576040805162461bcd60e51b8152602060048201526009602482015268216c6576657261676560b81b604482015290519081900360640190fd5b600080613a18611ce5565b90506000613a268683613cd5565b9050600081118015613a3c5750613a3c81614c38565b15613b3d57600d5460408051603160f81b60208083019190915282518083036001018152602183019384905263701195a160e11b9093523060258301818152604584018790526060606585019081528551608586015285516001600160a01b039097169663e0232b42969395899560a5909101919085019080838360005b83811015613ad2578181015183820152602001613aba565b50505050905090810190601f168015613aff5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015613b2057600080fd5b505af1158015613b34573d6000803e3d6000fd5b50505050613c07565b85821015613c0757613b4d61234b565b925085613b5a83856141b9565b1115613b6d57613b6a8683613cd5565b92505b60008051602061511f8339815191526001600160a01b031663c5ebeaec846040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015613bc157600080fd5b505af1158015613bd5573d6000803e3d6000fd5b505050506040513d6020811015613beb57600080fd5b50613bf6905061333e565b613c0082846141b9565b9150613b3d565b505050505050565b6000613c19612334565b90506134c5816134d7565b6009546001600160a01b031681565b600080613c3e61124d565b90506000613c4a611ef4565b905080821115613c83576000613c5e612334565b90506000613c6b82612420565b9050613c76816134d7565b6001945050505050610fbd565b60009250505090565b6000613cce83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614ceb565b9392505050565b6000613cce83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614d8d565b600082613d2657506000611c22565b82820282848281613d3357fe5b0414613cce5760405162461bcd60e51b815260040180806020018281038252602181526020018061513f6021913960400191505060405180910390fd5b600080613d7b61272a565b905060008390508060008051602061511f8339815191526001600160a01b0316633b1d21a26040518163ffffffff1660e01b815260040160206040518083038186803b158015613dca57600080fd5b505afa158015613dde573d6000803e3d6000fd5b505050506040513d6020811015613df457600080fd5b50511015613e3b576040805162461bcd60e51b815260206004820152600f60248201526e21636173682d6c697175696469747960881b604482015290519081900360640190fd5b6000613e45612038565b90506000613e51611ce5565b90506000613e5d611cad565b90506000613e77670de0b6b3a764000061127c8785613d17565b9050600084821115613ef757613e9d613e98613e91612334565b8690613cd5565b614c38565b9050306001600160a01b031663f53f13506040518163ffffffff1660e01b8152600401600060405180830381600087803b158015613eda57600080fd5b505af1158015613eee573d6000803e3d6000fd5b50505050613f61565b613f0082614c38565b90503063eb514af9613f128685613cd5565b6040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015613f4857600080fd5b505af1158015613f5c573d6000803e3d6000fd5b505050505b60008051602061511f83398151915263852a12e382613f8057876140e9565b600d546040805163287a0f7760e01b815290516140e9926001600160a01b03169163287a0f77916004808301926020929190829003018186803b158015613fc657600080fd5b505afa158015613fda573d6000803e3d6000fd5b505050506040513d6020811015613ff057600080fd5b5051600d5460408051634de5aab960e11b8152905161127c926140e2926001600160a01b0390911691639bcb557291600480820192602092909190829003018186803b15801561403f57600080fd5b505afa158015614053573d6000803e3d6000fd5b505050506040513d602081101561406957600080fd5b5051600d546040805163287a0f7760e01b815290516001600160a01b039092169163287a0f7791600480820192602092909190829003018186803b1580156140b057600080fd5b505afa1580156140c4573d6000803e3d6000fd5b505050506040513d60208110156140da57600080fd5b505190613cd5565b8b90613d17565b6040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b15801561411f57600080fd5b505af1158015614133573d6000803e3d6000fd5b505050506040513d602081101561414957600080fd5b505115614195576040805162461bcd60e51b81526020600482015260156024820152742172656465656d496e5769746864726177536f6d6560581b604482015290519081900360640190fd5b600061419f61272a565b90506141ab8189613cd5565b9a9950505050505050505050565b600082820183811015613cce576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b732260fac5e5542a773aa44fbcfedf7c193bc2c59991565b60035460ff161515600114156125605760035461425890839061010090046001600160a01b0316836143b8565b600354604080516370a0823160e01b8152306004820152905160009261010090046001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156142a857600080fd5b505afa1580156142bc573d6000803e3d6000fd5b505050506040513d60208110156142d257600080fd5b50516004546003549192506142f99161010090046001600160a01b03908116911683614361565b6004805460408051635ad6dca560e11b8152928301849052516001600160a01b039091169163b5adb94a91602480830192600092919082900301818387803b15801561434457600080fd5b505af1158015614358573d6000803e3d6000fd5b50505050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526143b3908490614de7565b505050565b6001600160a01b0382166143cb57600080fd5b600c546143e6906001600160a01b0385811691166000614b25565b600c54614400906001600160a01b03858116911683614b25565b6003546060906001600160a01b038481166101009092041614801561442c575060035460ff1615156001145b156146ab576001600160a01b03841673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4814156144d7576040805160028082526060820183529091602083019080368337019050509050838160008151811061448457fe5b60200260200101906001600160a01b031690816001600160a01b03168152505082816001815181106144b257fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506146a6565b6007546001600160a01b038581169116148061450057506006546001600160a01b038581169116145b156145e65760408051600480825260a082019092529060208201608080368337019050509050838160008151811061453457fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28160018151811061457657fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48816002815181106145b857fe5b60200260200101906001600160a01b031690816001600160a01b03168152505082816003815181106144b257fe5b604080516003808252608082019092529060208201606080368337019050509050838160008151811061461557fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb488160018151811061465757fe5b60200260200101906001600160a01b031690816001600160a01b031681525050828160028151811061468557fe5b60200260200101906001600160a01b031690816001600160a01b0316815250505b614813565b6001600160a01b03841673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc214806146f257506001600160a01b03831673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2145b15614753576040805160028082526060820183529091602083019080368337019050509050838160008151811061472557fe5b60200260200101906001600160a01b031690816001600160a01b031681525050828160018151811061468557fe5b604080516003808252608082019092529060208201606080368337019050509050838160008151811061478257fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2816001815181106147c457fe5b60200260200101906001600160a01b031690816001600160a01b03168152505082816002815181106147f257fe5b60200260200101906001600160a01b031690816001600160a01b0316815250505b600c546001600160a01b03166338ed1739836000843061483442603c6141b9565b6040518663ffffffff1660e01b81526004018086815260200185815260200180602001846001600160a01b03168152602001838152602001828103825285818151815260200191508051906020019060200280838360005b838110156148a457818101518382015260200161488c565b505050509050019650505050505050600060405180830381600087803b1580156148cd57600080fd5b505af11580156148e1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561490a57600080fd5b8101908080516040519392919084600160201b82111561492957600080fd5b90830190602082018581111561493e57600080fd5b82518660208202830111600160201b8211171561495a57600080fd5b82525081516020918201928201910280838360005b8381101561498757818101518382015260200161496f565b505050509050016040525050505050505050565b6009546000906001600160a01b031633146149eb576040805162461bcd60e51b815260206004820152600b60248201526a10b1b7b73a3937b63632b960a91b604482015290519081900360640190fd5b6005546001600160a01b0383811691161415614a37576040805162461bcd60e51b815260206004808301919091526024820152631dd85b9d60e21b604482015290519081900360640190fd5b604080516370a0823160e01b815230600482015290516001600160a01b038416916370a08231916024808301926020929190829003018186803b158015614a7d57600080fd5b505afa158015614a91573d6000803e3d6000fd5b505050506040513d6020811015614aa757600080fd5b5051600954909150612447906001600160a01b03848116911683614361565b6000806000614ad361510b565b614add8686614e98565b90925090506000826003811115614af057fe5b14614b015750915060009050614b13565b6000614b0c82614f00565b9350935050505b9250929050565b6134c56113a3610ff0565b801580614bab575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b158015614b7d57600080fd5b505afa158015614b91573d6000803e3d6000fd5b505050506040513d6020811015614ba757600080fd5b5051155b614be65760405162461bcd60e51b815260040180806020018281038252603681526020018061518a6036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b1790526143b3908490614de7565b600d54600090600160a01b900460ff168015614c5e5750600d546001600160a01b031615155b8015611c225750600554600d54604080516370a0823160e01b81526001600160a01b0392831660048201529051859392909216916370a0823191602480820192602092909190829003018186803b158015614cb857600080fd5b505afa158015614ccc573d6000803e3d6000fd5b505050506040513d6020811015614ce257600080fd5b50511192915050565b60008183614d775760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614d3c578181015183820152602001614d24565b50505050905090810190601f168015614d695780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581614d8357fe5b0495945050505050565b60008184841115614ddf5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315614d3c578181015183820152602001614d24565b505050900390565b6060614e3c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614f0f9092919063ffffffff16565b8051909150156143b357808060200190516020811015614e5b57600080fd5b50516143b35760405162461bcd60e51b815260040180806020018281038252602a815260200180615160602a913960400191505060405180910390fd5b6000614ea261510b565b600080614eb3866000015186614f26565b90925090506000826003811115614ec657fe5b14614ee557506040805160208101909152600081529092509050614b13565b60408051602081019091529081526000969095509350505050565b51670de0b6b3a7640000900490565b6060614f1e8484600085614f65565b949350505050565b60008083614f3957506000905080614b13565b83830283858281614f4657fe5b0414614f5a57600260009250925050614b13565b600092509050614b13565b6060614f70856150d2565b614fc1576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b602083106150005780518252601f199092019160209182019101614fe1565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114615062576040519150601f19603f3d011682016040523d82523d6000602084013e615067565b606091505b5091509150811561507b579150614f1e9050565b80511561508b5780518082602001fd5b60405162461bcd60e51b8152602060048201818152865160248401528651879391928392604401919085019080838360008315614d3c578181015183820152602001614d24565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590614f1e575050151592915050565b604051806020016040528060008152509056fe000000000000000000000000ccf4429db6322d5c611ee964527d42e5d685dd6a536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a2646970667358221220b00e35e72a8c459b3d7b2c65cec4b381d84733f0e1a8539f8f6e26c074ebaddd64736f6c634300060c003300000000000000000000000043229759e12efbe3e2a0fb0510b15e516d0464420000000000000000000000000bd1d668d8e83d14252f2e01d5873df77a6511f00000000000000000000000004bf5059065541a2b176500928e91fbfd0b121d070000000000000000000000005dae9b27313670663b34ac8bffd18825bb9df736
Deployed Bytecode
0x6080604052600436106104735760003560e01c8063654028821161024a578063ab033ea911610139578063cc32d176116100b6578063eb514af91161007a578063eb514af914610e5a578063f4aa3a8d14610e84578063f53f135014610eae578063f77c479114610ec3578063fff6cae914610ed857610473565b8063cc32d17614610d6f578063cd04f09514610d84578063ce7079ba14610e1b578063d0e30db014610e30578063d33219b414610e4557610473565b8063b9e37489116100fd578063b9e3748914610cca578063bdacb30314610cdf578063c1a3d44c14610d12578063c7b9d53014610d27578063c92aecc414610d5a57610473565b8063ab033ea914610c25578063ac41ceb314610c58578063ae104b2f14610c6d578063b01db4ec14610ca0578063b635b8ae14610cb557610473565b8063857a52b8116101c75780639c4b81631161018b5780639c4b816314610b895780639eb52f6114610b9e578063a1e003e414610bb3578063a2d9f4dc14610bdd578063a890dd9014610c1057610473565b8063857a52b814610aeb5780638778878214610b0057806392eefe9b14610b155780639324f4fe14610b485780639a9b567d14610b5d57610473565b806377da835a1161020e57806377da835a14610a8257806377e741c714610a975780637cc79113146105b95780638081e1cf14610ac1578063853828b614610ad657610473565b806365402882146109ed57806370897b2314610a19578063722713f714610a43578063726d1f2e14610a585780637396a62614610a6d57610473565b8063302ab80d116103665780634a183ffc116102e35780635aa6e675116102a75780635aa6e675146109845780635bfb92ce146109995780635c208490146109ae5780635eefb092146109c35780635fe3b567146109d857610473565b80634a183ffc146108e85780634df268b5146108fd57806351cff8d914610912578063575a86b21461094557806359bca6791461095a57610473565b80633cdc53891161032a5780633cdc5389146108615780633fc8cef3146108765780634032b72b1461088b578063463289ed146108be5780634641257d146108d357610473565b8063302ab80d146107c55780633355104d146107ef5780633865cc97146108045780633bbd64bc146108195780633c5dae941461084c57610473565b806314f7910c116103f45780631f1fcd51116103b85780631f1fcd51146107475780631fe4a6861461075c5780632a99417d146107715780632bfc9c23146107865780632e1a7d4d1461079b57610473565b806314f7910c1461062b57806315ac03fd14610640578063160d0da51461065557806317d7de7c1461067e5780631cff79cd1461069357610473565b8063115880861161043b57806311588086146105a457806313bd4b95146105b957806314a1fe02146105b957806314ae9f2e146105ce57806314e6ac091461060157610473565b806301a4b1691461047857806305166eff146105025780630ea8b3bf14610537578063109d0af81461055e578063112666b71461058f575b600080fd5b34801561048457600080fd5b5061048d610eed565b6040805160208082528351818301528351919283929083019185019080838360005b838110156104c75781810151838201526020016104af565b50505050905090810190601f1680156104f45780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561050e57600080fd5b506105356004803603602081101561052557600080fd5b50356001600160a01b0316610f10565b005b34801561054357600080fd5b5061054c610f85565b60408051918252519081900360200190f35b34801561056a57600080fd5b50610573610fc0565b604080516001600160a01b039092168252519081900360200190f35b34801561059b57600080fd5b50610573610fd8565b3480156105b057600080fd5b5061054c610ff0565b3480156105c557600080fd5b5061054c611013565b3480156105da57600080fd5b50610535600480360360208110156105f157600080fd5b50356001600160a01b031661101a565b34801561060d57600080fd5b506105356004803603602081101561062457600080fd5b503561109d565b34801561063757600080fd5b506105736110ed565b34801561064c57600080fd5b506105736110ff565b34801561066157600080fd5b5061066a611117565b604080519115158252519081900360200190f35b34801561068a57600080fd5b5061048d611120565b61048d600480360360408110156106a957600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156106d357600080fd5b8201836020820111156106e557600080fd5b803590602001918460018302840111600160201b8311171561070657600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061114c945050505050565b34801561075357600080fd5b5061057361122f565b34801561076857600080fd5b5061057361123e565b34801561077d57600080fd5b5061054c61124d565b34801561079257600080fd5b5061054c611282565b3480156107a757600080fd5b50610535600480360360208110156107be57600080fd5b50356112c8565b3480156107d157600080fd5b50610535600480360360208110156107e857600080fd5b5035611634565b3480156107fb57600080fd5b5061066a61169b565b34801561081057600080fd5b5061054c6116ab565b34801561082557600080fd5b5061066a6004803603602081101561083c57600080fd5b50356001600160a01b03166116b1565b34801561085857600080fd5b5061054c6116c6565b34801561086d57600080fd5b50610573611702565b34801561088257600080fd5b5061057361171a565b34801561089757600080fd5b50610535600480360360208110156108ae57600080fd5b50356001600160a01b0316611732565b3480156108ca57600080fd5b5061054c6117b8565b3480156108df57600080fd5b5061053561184f565b3480156108f457600080fd5b50610573611bac565b34801561090957600080fd5b5061054c611bbb565b34801561091e57600080fd5b5061054c6004803603602081101561093557600080fd5b50356001600160a01b0316611bc1565b34801561095157600080fd5b50610573611c28565b34801561096657600080fd5b506105356004803603602081101561097d57600080fd5b5035611c37565b34801561099057600080fd5b50610573611c9e565b3480156109a557600080fd5b5061054c611cad565b3480156109ba57600080fd5b5061054c611ce5565b3480156109cf57600080fd5b5061054c611d66565b3480156109e457600080fd5b50610573611dc9565b3480156109f957600080fd5b5061053560048036036020811015610a1057600080fd5b50351515611de1565b348015610a2557600080fd5b5061053560048036036020811015610a3c57600080fd5b5035611e61565b348015610a4f57600080fd5b5061054c611eb1565b348015610a6457600080fd5b5061048d611ed1565b348015610a7957600080fd5b5061054c611ef4565b348015610a8e57600080fd5b5061054c611f29565b348015610aa357600080fd5b5061053560048036036020811015610aba57600080fd5b5035611fe8565b348015610acd57600080fd5b5061054c612038565b348015610ae257600080fd5b5061054c612088565b348015610af757600080fd5b5061057361223a565b348015610b0c57600080fd5b5061054c612252565b348015610b2157600080fd5b5061053560048036036020811015610b3857600080fd5b50356001600160a01b0316612258565b348015610b5457600080fd5b506105736122c5565b348015610b6957600080fd5b5061053560048036036020811015610b8057600080fd5b503515156122d4565b348015610b9557600080fd5b5061054c612334565b348015610baa57600080fd5b5061054c61234b565b348015610bbf57600080fd5b5061054c60048036036020811015610bd657600080fd5b5035612420565b348015610be957600080fd5b5061053560048036036020811015610c0057600080fd5b50356001600160a01b031661244c565b348015610c1c57600080fd5b506105736124bb565b348015610c3157600080fd5b5061053560048036036020811015610c4857600080fd5b50356001600160a01b03166124cf565b348015610c6457600080fd5b5061053561253e565b348015610c7957600080fd5b5061053560048036036020811015610c9057600080fd5b50356001600160a01b0316612564565b348015610cac57600080fd5b5061054c6125e8565b348015610cc157600080fd5b5061054c6126a8565b348015610cd657600080fd5b506105736126ae565b348015610ceb57600080fd5b5061053560048036036020811015610d0257600080fd5b50356001600160a01b03166126bd565b348015610d1e57600080fd5b5061054c61272a565b348015610d3357600080fd5b5061053560048036036020811015610d4a57600080fd5b50356001600160a01b0316612775565b348015610d6657600080fd5b506105736127e4565b348015610d7b57600080fd5b5061054c6127f6565b348015610d9057600080fd5b5061053560048036036080811015610da757600080fd5b6001600160a01b038235169160208101359160408201359190810190608081016060820135600160201b811115610ddd57600080fd5b820183602082011115610def57600080fd5b803590602001918460018302840111600160201b83111715610e1057600080fd5b5090925090506127fc565b348015610e2757600080fd5b5061057361332f565b348015610e3c57600080fd5b5061053561333e565b348015610e5157600080fd5b506105736134c8565b348015610e6657600080fd5b5061053560048036036020811015610e7d57600080fd5b50356134d7565b348015610e9057600080fd5b5061053560048036036020811015610ea757600080fd5b5035613910565b348015610eba57600080fd5b50610535613c0f565b348015610ecf57600080fd5b50610573613c24565b348015610ee457600080fd5b5061066a613c33565b60408051601960f91b602082015281518082036001018152602190910190915281565b6008546001600160a01b03163314610f5d576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600380546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b600080610f906116c6565b90506000610fb86ec097ce7bc90715b34b9f1000000000670de0b6b3a7640000849003613c8c565b925050505b90565b73c00e94cb662c3520282e6f5717214004a7f2688881565b73d513d22422a3062bd342ae374b4b9c20e0a9a07481565b600080610ffb611f29565b90506000611007611d66565b9050610fb88282613cd5565b620186a081565b6008546001600160a01b031633148061103d5750600a546001600160a01b031633145b61107c576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b6001600160a01b03166000908152601260205260409020805460ff19169055565b600b546001600160a01b031633146110e8576040805162461bcd60e51b81526020600482015260096024820152682174696d656c6f636b60b81b604482015290519081900360640190fd5b600255565b60008051602061511f83398151915281565b734ddc2d193948926d02f9b1fe9e1daa0718270ed581565b60035460ff1681565b6040805180820190915260128152715374726174656779436d706457627463563160701b602082015290565b600b546060906001600160a01b0316331461119a576040805162461bcd60e51b81526020600482015260096024820152682174696d656c6f636b60b81b604482015290519081900360640190fd5b6001600160a01b0383166111df576040805162461bcd60e51b8152602060048201526007602482015266085d185c99d95d60ca1b604482015290519081900360640190fd5b600080835160208501866113885a03f43d6040519250601f19601f6020830101168301604052808352806000602085013e81156001811461121f57611226565b8160208501fd5b50505092915050565b6005546001600160a01b031681565b600a546001600160a01b031681565b600080611258611ce5565b90506000611264612038565b9050610fb88261127c83670de0b6b3a7640000613d17565b90613c8c565b60008061128d6116c6565b90506112c28161127c600f5461127c68056bc75e2d631000006112bc60b6600e54613d1790919063ffffffff16565b90613d17565b91505090565b6009546001600160a01b03163314611315576040805162461bcd60e51b815260206004820152600b60248201526a10b1b7b73a3937b63632b960a91b604482015290519081900360640190fd5b600554604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561136057600080fd5b505afa158015611374573d6000803e3d6000fd5b505050506040513d602081101561138a57600080fd5b50519050818110156113b7576113a86113a38383613cd5565b613d70565b91506113b482826141b9565b91505b60006113d5620186a061127c60025486613d1790919063ffffffff16565b905060006113f5620186a061127c60015487613d1790919063ffffffff16565b60035490915060ff161515600114156114325760008061141d61141885856141b9565b614213565b9150915061142b828261422b565b505061153c565b60095460408051638d8f1e6760e01b815290516114b7926001600160a01b031691638d8f1e67916004808301926020929190829003018186803b15801561147857600080fd5b505afa15801561148c573d6000803e3d6000fd5b505050506040513d60208110156114a257600080fd5b50516005546001600160a01b03169084614361565b600954604080516361d027b360e01b8152905161153c926001600160a01b0316916361d027b3916004808301926020929190829003018186803b1580156114fd57600080fd5b505afa158015611511573d6000803e3d6000fd5b505050506040513d602081101561152757600080fd5b50516005546001600160a01b03169083614361565b60095460055460408051632988bb9f60e21b81526001600160a01b0392831660048201529051600093929092169163a622ee7c91602480820192602092909190829003018186803b15801561159057600080fd5b505afa1580156115a4573d6000803e3d6000fd5b505050506040513d60208110156115ba57600080fd5b505190506001600160a01b038116611602576040805162461bcd60e51b8152602060048201526006602482015265085d985d5b1d60d21b604482015290519081900360640190fd5b61162d8161161a846116148988613cd5565b90613cd5565b6005546001600160a01b03169190614361565b5050505050565b6008546001600160a01b03163314806116575750600a546001600160a01b031633145b611696576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600e55565b600d54600160a01b900460ff1681565b60105481565b60126020526000908152604090205460ff1681565b6000806116d16117b8565b90506000610fb86116fb600f5461127c670de0b6b3a7640000600e54613d1790919063ffffffff16565b8390613cd5565b732260fac5e5542a773aa44fbcfedf7c193bc2c59981565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6008546001600160a01b03163314806117555750600a546001600160a01b031633145b611794576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b6001600160a01b03166000908152601260205260409020805460ff19166001179055565b60408051638e8f294b60e01b815260008051602061511f833981519152600482015281516000928392733d9819210a31b4961b30ef54be2aed79b9c9cd3b92638e8f294b92602480840193919291829003018186803b15801561181a57600080fd5b505afa15801561182e573d6000803e3d6000fd5b505050506040513d604081101561184457600080fd5b506020015191505090565b3332148061186757506008546001600160a01b031633145b8061187c5750600a546001600160a01b031633145b61188557600080fd5b6040805160018082528183019092526060916020808301908036833701905050905060008051602061511f833981519152816000815181106118c357fe5b6001600160a01b039092166020928302919091018201526040805162e1ed9760e51b8152306004820181815260248301938452855160448401528551733d9819210a31b4961b30ef54be2aed79b9c9cd3b95631c3db2e0959394889492606490910191858101910280838360005b83811015611949578181015183820152602001611931565b505050509050019350505050600060405180830381600087803b15801561196f57600080fd5b505af1158015611983573d6000803e3d6000fd5b5050604080516370a0823160e01b815230600482015290516000935073c00e94cb662c3520282e6f5717214004a7f2688892506370a0823191602480820192602092909190829003018186803b1580156119dc57600080fd5b505afa1580156119f0573d6000803e3d6000fd5b505050506040513d6020811015611a0657600080fd5b505190508015611a3c57600554611a3c9073c00e94cb662c3520282e6f5717214004a7f26888906001600160a01b0316836143b8565b600554604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015611a8757600080fd5b505afa158015611a9b573d6000803e3d6000fd5b505050506040513d6020811015611ab157600080fd5b50516000805491925090611acf90620186a09061127c908590613d17565b60035490915060ff1615156001148015611ae95750600081115b15611b0957600554611b04906001600160a01b03168261422b565b611b98565b8115611b9857600954604080516361d027b360e01b81529051611b98926001600160a01b0316916361d027b3916004808301926020929190829003018186803b158015611b5557600080fd5b505afa158015611b69573d6000803e3d6000fd5b505050506040513d6020811015611b7f57600080fd5b505160005461161a90620186a09061127c908790613d17565b8115611ba657611ba661333e565b50505050565b6007546001600160a01b031681565b600e5481565b600060008051602061511f8339815191526001600160a01b0383161415611c19576040805162461bcd60e51b815260206004820152600760248201526610b1aa37b5b2b760c91b604482015290519081900360640190fd5b611c228261499b565b92915050565b6004546001600160a01b031681565b6008546001600160a01b0316331480611c5a5750600a546001600160a01b031633145b611c99576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b601055565b6008546001600160a01b031681565b600080611cb8611ce5565b90506000611cc4612038565b9050610fb8611cd38383613cd5565b61127c84670de0b6b3a7640000613d17565b60408051633af9e66960e01b8152306004820152905160009160008051602061511f83398151915291633af9e6699160248082019260209290919082900301818787803b158015611d3557600080fd5b505af1158015611d49573d6000803e3d6000fd5b505050506040513d6020811015611d5f57600080fd5b5051905090565b604080516395dd919360e01b8152306004820152905160009160008051602061511f833981519152916395dd919391602480820192602092909190829003018186803b158015611db557600080fd5b505afa158015611d49573d6000803e3d6000fd5b733d9819210a31b4961b30ef54be2aed79b9c9cd3b81565b6008546001600160a01b0316331480611e045750600a546001600160a01b031633145b611e43576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600d8054911515600160a01b0260ff60a01b19909216919091179055565b600b546001600160a01b03163314611eac576040805162461bcd60e51b81526020600482015260096024820152682174696d656c6f636b60b81b604482015290519081900360640190fd5b600055565b6000611ecc611ebe610ff0565b611ec661272a565b906141b9565b905090565b60408051603160f81b602082015281518082036001018152602190910190915281565b600080611eff6117b8565b90506000610fb86116fb60115461127c670de0b6b3a7640000601054613d1790919063ffffffff16565b600080600060008051602061511f8339815191526001600160a01b031663c37f68e2306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060806040518083038186803b158015611f8957600080fd5b505afa158015611f9d573d6000803e3d6000fd5b505050506040513d6080811015611fb357600080fd5b50602080820151606090920151604080519283019052808252919350909150600090611fdf9084614ac6565b94505050505090565b600b546001600160a01b03163314612033576040805162461bcd60e51b81526020600482015260096024820152682174696d656c6f636b60b81b604482015290519081900360640190fd5b600155565b604080516305eff7ef60e21b8152306004820152905160009160008051602061511f833981519152916317bfdfbc9160248082019260209290919082900301818787803b158015611d3557600080fd5b6009546000906001600160a01b031633146120d8576040805162461bcd60e51b815260206004820152600b60248201526a10b1b7b73a3937b63632b960a91b604482015290519081900360640190fd5b6120e0614b1a565b600554604080516370a0823160e01b815230600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b15801561212b57600080fd5b505afa15801561213f573d6000803e3d6000fd5b505050506040513d602081101561215557600080fd5b505160095460055460408051632988bb9f60e21b81526001600160a01b0392831660048201529051939450600093919092169163a622ee7c916024808301926020929190829003018186803b1580156121ad57600080fd5b505afa1580156121c1573d6000803e3d6000fd5b505050506040513d60208110156121d757600080fd5b505190506001600160a01b03811661221f576040805162461bcd60e51b8152602060048201526006602482015265085d985d5b1d60d21b604482015290519081900360640190fd5b600554612236906001600160a01b03168284614361565b5090565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b60005481565b600b546001600160a01b031633146122a3576040805162461bcd60e51b81526020600482015260096024820152682174696d656c6f636b60b81b604482015290519081900360640190fd5b600980546001600160a01b0319166001600160a01b0392909216919091179055565b600d546001600160a01b031681565b6008546001600160a01b03163314612321576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b6003805460ff1916911515919091179055565b60008061233f611ce5565b90506000611007612038565b600080612356611ce5565b90506000612362612038565b60408051638e8f294b60e01b815260008051602061511f83398151915260048201528151929350600092733d9819210a31b4961b30ef54be2aed79b9c9cd3b92638e8f294b9260248082019391829003018186803b1580156123c357600080fd5b505afa1580156123d7573d6000803e3d6000fd5b505050506040513d60408110156123ed57600080fd5b5060200151905061241861271061127c61270f6112bc86611614670de0b6b3a7640000858b8a613d17565b935050505090565b60008061242b610f85565b9050612443670de0b6b3a764000061127c8584613d17565b9150505b919050565b6008546001600160a01b03163314612499576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b60035461010090046001600160a01b031681565b6008546001600160a01b0316331461251c576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600880546001600160a01b0319166001600160a01b0392909216919091179055565b6000612548612334565b9050600061255582612420565b905061256081613910565b5050565b6008546001600160a01b03163314806125875750600a546001600160a01b031633145b6125c6576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b60408051631ea6374160e01b815273c00e94cb662c3520282e6f5717214004a7f268886004820152733d9819210a31b4961b30ef54be2aed79b9c9cd3b60248201523060448201529051600091829173d513d22422a3062bd342ae374b4b9c20e0a9a07491631ea6374191606480830192608092919082900301818787803b15801561267357600080fd5b505af1158015612687573d6000803e3d6000fd5b505050506040513d608081101561269d57600080fd5b506060015191505090565b60025481565b600c546001600160a01b031681565b600b546001600160a01b03163314612708576040805162461bcd60e51b81526020600482015260096024820152682174696d656c6f636b60b81b604482015290519081900360640190fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b600554604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015611db557600080fd5b6008546001600160a01b031633146127c2576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b6d4946c0e9f43f4dee607b0ef1fa1c81565b60015481565b600d54600160a01b900460ff16801561281f5750600d546001600160a01b031615155b61285f576040805162461bcd60e51b815260206004820152600c60248201526b10b737a33630b9b42637b0b760a11b604482015290519081900360640190fd5b6005546001600160a01b038681169116146128b7576040805162461bcd60e51b815260206004820152601360248201527210b6b4b9b6b0ba31b4233630b9b42a37b5b2b760691b604482015290519081900360640190fd5b836128c061272a565b1015612909576040805162461bcd60e51b8152602060048201526013602482015272085a5b9d985b1a59119b185cda105b5bdd5b9d606a1b604482015290519081900360640190fd5b600061291585856141b9565b9050606083838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250600d546040805163095ea7b360e01b81526001600160a01b03909216600483015260248201839052519596506d4946c0e9f43f4dee607b0ef1fa1c9563095ea7b3955060448083019550602094509092918390030190829087803b1580156129b257600080fd5b505af11580156129c6573d6000803e3d6000fd5b505050506040513d60208110156129dc57600080fd5b5050600d546040805163095ea7b360e01b81526001600160a01b0390921660048301526000196024830152516d4946c0e9f43f4dee607b0ef1fa1c9163095ea7b39160448083019260209291908290030181600087803b158015612a3f57600080fd5b505af1158015612a53573d6000803e3d6000fd5b505050506040513d6020811015612a6957600080fd5b505080518190600090612a7857fe5b6020910101516001600160f81b031916603160f81b1415612dd057612a9b61333e565b81612aa461234b565b1015612aef576040805162461bcd60e51b815260206004820152601560248201527421626f72726f7761626c65466c617368526570617960581b604482015290519081900360640190fd5b60008051602061511f8339815191526001600160a01b031663c5ebeaec836040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015612b4357600080fd5b505af1158015612b57573d6000803e3d6000fd5b505050506040513d6020811015612b6d57600080fd5b505115612bb8576040805162461bcd60e51b815260206004820152601460248201527321626f72726f77466c6173684c6576657261676560601b604482015290519081900360640190fd5b7f160548f48e39cd1b13c1762e9aeb707b3ba179f6e17ddc3a88e8de040ddf3a7486868686600d60009054906101000a90046001600160a01b03166001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b158015612c2b57600080fd5b505afa158015612c3f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015612c6857600080fd5b8101908080516040519392919084600160201b821115612c8757600080fd5b908301906020820185811115612c9c57600080fd5b8251600160201b811182820188101715612cb557600080fd5b82525081516020918201929091019080838360005b83811015612ce2578181015183820152602001612cca565b50505050905090810190601f168015612d0f5780820380516001836020036101000a031916815260200191505b5060405250505060405180868152602001858152602001806020018060200183810383528686828181526020019250808284376000838201819052601f909101601f191690920185810384528651815286516020918201939188019250908190849084905b83811015612d8c578181015183820152602001612d74565b50505050905090810190601f168015612db95780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390a1613250565b80600081518110612ddd57fe5b6020910101516001600160f81b031916601960f91b141561325057612e26732260fac5e5542a773aa44fbcfedf7c193bc2c59960008051602061511f8339815191526000614b25565b612e53732260fac5e5542a773aa44fbcfedf7c193bc2c59960008051602061511f83398151915288614b25565b60008051602061511f8339815191526001600160a01b0316630e752702876040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015612ea757600080fd5b505af1158015612ebb573d6000803e3d6000fd5b505050506040513d6020811015612ed157600080fd5b505115612f1d576040805162461bcd60e51b8152602060048201526015602482015274217265706179466c61736844656c6576657261676560581b604482015290519081900360640190fd5b81612f2661234b565b1015612f71576040805162461bcd60e51b815260206004820152601560248201527421626f72726f7761626c65466c617368526570617960581b604482015290519081900360640190fd5b60008051602061511f8339815191526001600160a01b031663852a12e3836040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015612fc557600080fd5b505af1158015612fd9573d6000803e3d6000fd5b505050506040513d6020811015612fef57600080fd5b50511561303c576040805162461bcd60e51b81526020600482015260166024820152752172656465656d466c61736844656c6576657261676560501b604482015290519081900360640190fd5b7fa6bedcf9169bb8eda4b6e84a0872589b7e6af9d164a399143c85371b0876536186868686600d60009054906101000a90046001600160a01b03166001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156130af57600080fd5b505afa1580156130c3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156130ec57600080fd5b8101908080516040519392919084600160201b82111561310b57600080fd5b90830190602082018581111561312057600080fd5b8251600160201b81118282018810171561313957600080fd5b82525081516020918201929091019080838360005b8381101561316657818101518382015260200161314e565b50505050905090810190601f1680156131935780820380516001836020036101000a031916815260200191505b5060405250505060405180868152602001858152602001806020018060200183810383528686828181526020019250808284376000838201819052601f909101601f191690920185810384528651815286516020918201939188019250908190849084905b838110156132105781810151838201526020016131f8565b50505050905090810190601f16801561323d5780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390a15b8161325961272a565b10156132a1576040805162461bcd60e51b81526020600482015260126024820152712164656669636974466c617368526570617960701b604482015290519081900360640190fd5b600554600d546040805163a9059cbb60e01b81526001600160a01b039283166004820152602481018690529051919092169163a9059cbb9160448083019260209291908290030181600087803b1580156132fa57600080fd5b505af115801561330e573d6000803e3d6000fd5b505050506040513d602081101561332457600080fd5b505050505050505050565b6006546001600160a01b031681565b600554604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561338957600080fd5b505afa15801561339d573d6000803e3d6000fd5b505050506040513d60208110156133b357600080fd5b5051905080156134c5576005546133e3906001600160a01b031660008051602061511f8339815191526000614b25565b600554613408906001600160a01b031660008051602061511f83398151915283614b25565b60008051602061511f8339815191526001600160a01b031663a0712d68826040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b15801561345c57600080fd5b505af1158015613470573d6000803e3d6000fd5b505050506040513d602081101561348657600080fd5b5051156134c5576040805162461bcd60e51b81526020600482015260086024820152670859195c1bdcda5d60c21b604482015290519081900360640190fd5b50565b600b546001600160a01b031681565b3360009081526012602052604090205460ff16806134f457503330145b806135095750600a546001600160a01b031633145b8061351e57506008546001600160a01b031633145b61355a576040805162461bcd60e51b8152602060048201526008602482015267216b65657065727360c01b604482015290519081900360640190fd5b6000613564612334565b90506000613570611ce5565b90508183101580156135825750808311155b6135c1576040805162461bcd60e51b815260206004820152600b60248201526a2164656c6576657261676560a81b604482015290519081900360640190fd5b60006135cb61234b565b905060006135d98386613cd5565b90506000811180156135ef57506135ef81614c38565b156136f057600d5460408051601960f91b60208083019190915282518083036001018152602183019384905263701195a160e11b9093523060258301818152604584018790526060606585019081528551608586015285516001600160a01b039097169663e0232b42969395899560a5909101919085019080838360005b8381101561368557818101518382015260200161366d565b50505050905090810190601f1680156136b25780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156136d357600080fd5b505af11580156136e7573d6000803e3d6000fd5b5050505061162d565b846136fb8484613cd5565b101561370e5761370b8386613cd5565b91505b60008051602061511f8339815191526001600160a01b031663852a12e3836040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b15801561376257600080fd5b505af1158015613776573d6000803e3d6000fd5b505050506040513d602081101561378c57600080fd5b5051156137e0576040805162461bcd60e51b815260206004820152601860248201527f2172656465656d496e44656c65766572616765556e74696c0000000000000000604482015290519081900360640190fd5b61380e732260fac5e5542a773aa44fbcfedf7c193bc2c59960008051602061511f8339815191526000614b25565b61383b732260fac5e5542a773aa44fbcfedf7c193bc2c59960008051602061511f83398151915284614b25565b60008051602061511f8339815191526001600160a01b0316630e752702836040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b15801561388f57600080fd5b505af11580156138a3573d6000803e3d6000fd5b505050506040513d60208110156138b957600080fd5b5051156138f6576040805162461bcd60e51b815260206004820152600660248201526521726570617960d01b604482015290519081900360640190fd5b6139008383613cd5565b92508483116136f0575050505050565b3360009081526012602052604090205460ff168061392d57503330145b806139425750600a546001600160a01b031633145b8061395757506008546001600160a01b031633145b613993576040805162461bcd60e51b8152602060048201526008602482015267216b65657065727360c01b604482015290519081900360640190fd5b600061399d610f85565b905060006139a9612334565b90508083101580156139d057506139cc670de0b6b3a764000061127c8385613d17565b8311155b613a0d576040805162461bcd60e51b8152602060048201526009602482015268216c6576657261676560b81b604482015290519081900360640190fd5b600080613a18611ce5565b90506000613a268683613cd5565b9050600081118015613a3c5750613a3c81614c38565b15613b3d57600d5460408051603160f81b60208083019190915282518083036001018152602183019384905263701195a160e11b9093523060258301818152604584018790526060606585019081528551608586015285516001600160a01b039097169663e0232b42969395899560a5909101919085019080838360005b83811015613ad2578181015183820152602001613aba565b50505050905090810190601f168015613aff5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015613b2057600080fd5b505af1158015613b34573d6000803e3d6000fd5b50505050613c07565b85821015613c0757613b4d61234b565b925085613b5a83856141b9565b1115613b6d57613b6a8683613cd5565b92505b60008051602061511f8339815191526001600160a01b031663c5ebeaec846040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015613bc157600080fd5b505af1158015613bd5573d6000803e3d6000fd5b505050506040513d6020811015613beb57600080fd5b50613bf6905061333e565b613c0082846141b9565b9150613b3d565b505050505050565b6000613c19612334565b90506134c5816134d7565b6009546001600160a01b031681565b600080613c3e61124d565b90506000613c4a611ef4565b905080821115613c83576000613c5e612334565b90506000613c6b82612420565b9050613c76816134d7565b6001945050505050610fbd565b60009250505090565b6000613cce83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614ceb565b9392505050565b6000613cce83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614d8d565b600082613d2657506000611c22565b82820282848281613d3357fe5b0414613cce5760405162461bcd60e51b815260040180806020018281038252602181526020018061513f6021913960400191505060405180910390fd5b600080613d7b61272a565b905060008390508060008051602061511f8339815191526001600160a01b0316633b1d21a26040518163ffffffff1660e01b815260040160206040518083038186803b158015613dca57600080fd5b505afa158015613dde573d6000803e3d6000fd5b505050506040513d6020811015613df457600080fd5b50511015613e3b576040805162461bcd60e51b815260206004820152600f60248201526e21636173682d6c697175696469747960881b604482015290519081900360640190fd5b6000613e45612038565b90506000613e51611ce5565b90506000613e5d611cad565b90506000613e77670de0b6b3a764000061127c8785613d17565b9050600084821115613ef757613e9d613e98613e91612334565b8690613cd5565b614c38565b9050306001600160a01b031663f53f13506040518163ffffffff1660e01b8152600401600060405180830381600087803b158015613eda57600080fd5b505af1158015613eee573d6000803e3d6000fd5b50505050613f61565b613f0082614c38565b90503063eb514af9613f128685613cd5565b6040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015613f4857600080fd5b505af1158015613f5c573d6000803e3d6000fd5b505050505b60008051602061511f83398151915263852a12e382613f8057876140e9565b600d546040805163287a0f7760e01b815290516140e9926001600160a01b03169163287a0f77916004808301926020929190829003018186803b158015613fc657600080fd5b505afa158015613fda573d6000803e3d6000fd5b505050506040513d6020811015613ff057600080fd5b5051600d5460408051634de5aab960e11b8152905161127c926140e2926001600160a01b0390911691639bcb557291600480820192602092909190829003018186803b15801561403f57600080fd5b505afa158015614053573d6000803e3d6000fd5b505050506040513d602081101561406957600080fd5b5051600d546040805163287a0f7760e01b815290516001600160a01b039092169163287a0f7791600480820192602092909190829003018186803b1580156140b057600080fd5b505afa1580156140c4573d6000803e3d6000fd5b505050506040513d60208110156140da57600080fd5b505190613cd5565b8b90613d17565b6040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b15801561411f57600080fd5b505af1158015614133573d6000803e3d6000fd5b505050506040513d602081101561414957600080fd5b505115614195576040805162461bcd60e51b81526020600482015260156024820152742172656465656d496e5769746864726177536f6d6560581b604482015290519081900360640190fd5b600061419f61272a565b90506141ab8189613cd5565b9a9950505050505050505050565b600082820183811015613cce576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b732260fac5e5542a773aa44fbcfedf7c193bc2c59991565b60035460ff161515600114156125605760035461425890839061010090046001600160a01b0316836143b8565b600354604080516370a0823160e01b8152306004820152905160009261010090046001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156142a857600080fd5b505afa1580156142bc573d6000803e3d6000fd5b505050506040513d60208110156142d257600080fd5b50516004546003549192506142f99161010090046001600160a01b03908116911683614361565b6004805460408051635ad6dca560e11b8152928301849052516001600160a01b039091169163b5adb94a91602480830192600092919082900301818387803b15801561434457600080fd5b505af1158015614358573d6000803e3d6000fd5b50505050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526143b3908490614de7565b505050565b6001600160a01b0382166143cb57600080fd5b600c546143e6906001600160a01b0385811691166000614b25565b600c54614400906001600160a01b03858116911683614b25565b6003546060906001600160a01b038481166101009092041614801561442c575060035460ff1615156001145b156146ab576001600160a01b03841673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4814156144d7576040805160028082526060820183529091602083019080368337019050509050838160008151811061448457fe5b60200260200101906001600160a01b031690816001600160a01b03168152505082816001815181106144b257fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506146a6565b6007546001600160a01b038581169116148061450057506006546001600160a01b038581169116145b156145e65760408051600480825260a082019092529060208201608080368337019050509050838160008151811061453457fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28160018151811061457657fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48816002815181106145b857fe5b60200260200101906001600160a01b031690816001600160a01b03168152505082816003815181106144b257fe5b604080516003808252608082019092529060208201606080368337019050509050838160008151811061461557fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb488160018151811061465757fe5b60200260200101906001600160a01b031690816001600160a01b031681525050828160028151811061468557fe5b60200260200101906001600160a01b031690816001600160a01b0316815250505b614813565b6001600160a01b03841673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc214806146f257506001600160a01b03831673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2145b15614753576040805160028082526060820183529091602083019080368337019050509050838160008151811061472557fe5b60200260200101906001600160a01b031690816001600160a01b031681525050828160018151811061468557fe5b604080516003808252608082019092529060208201606080368337019050509050838160008151811061478257fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2816001815181106147c457fe5b60200260200101906001600160a01b031690816001600160a01b03168152505082816002815181106147f257fe5b60200260200101906001600160a01b031690816001600160a01b0316815250505b600c546001600160a01b03166338ed1739836000843061483442603c6141b9565b6040518663ffffffff1660e01b81526004018086815260200185815260200180602001846001600160a01b03168152602001838152602001828103825285818151815260200191508051906020019060200280838360005b838110156148a457818101518382015260200161488c565b505050509050019650505050505050600060405180830381600087803b1580156148cd57600080fd5b505af11580156148e1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561490a57600080fd5b8101908080516040519392919084600160201b82111561492957600080fd5b90830190602082018581111561493e57600080fd5b82518660208202830111600160201b8211171561495a57600080fd5b82525081516020918201928201910280838360005b8381101561498757818101518382015260200161496f565b505050509050016040525050505050505050565b6009546000906001600160a01b031633146149eb576040805162461bcd60e51b815260206004820152600b60248201526a10b1b7b73a3937b63632b960a91b604482015290519081900360640190fd5b6005546001600160a01b0383811691161415614a37576040805162461bcd60e51b815260206004808301919091526024820152631dd85b9d60e21b604482015290519081900360640190fd5b604080516370a0823160e01b815230600482015290516001600160a01b038416916370a08231916024808301926020929190829003018186803b158015614a7d57600080fd5b505afa158015614a91573d6000803e3d6000fd5b505050506040513d6020811015614aa757600080fd5b5051600954909150612447906001600160a01b03848116911683614361565b6000806000614ad361510b565b614add8686614e98565b90925090506000826003811115614af057fe5b14614b015750915060009050614b13565b6000614b0c82614f00565b9350935050505b9250929050565b6134c56113a3610ff0565b801580614bab575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b158015614b7d57600080fd5b505afa158015614b91573d6000803e3d6000fd5b505050506040513d6020811015614ba757600080fd5b5051155b614be65760405162461bcd60e51b815260040180806020018281038252603681526020018061518a6036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b1790526143b3908490614de7565b600d54600090600160a01b900460ff168015614c5e5750600d546001600160a01b031615155b8015611c225750600554600d54604080516370a0823160e01b81526001600160a01b0392831660048201529051859392909216916370a0823191602480820192602092909190829003018186803b158015614cb857600080fd5b505afa158015614ccc573d6000803e3d6000fd5b505050506040513d6020811015614ce257600080fd5b50511192915050565b60008183614d775760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614d3c578181015183820152602001614d24565b50505050905090810190601f168015614d695780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581614d8357fe5b0495945050505050565b60008184841115614ddf5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315614d3c578181015183820152602001614d24565b505050900390565b6060614e3c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614f0f9092919063ffffffff16565b8051909150156143b357808060200190516020811015614e5b57600080fd5b50516143b35760405162461bcd60e51b815260040180806020018281038252602a815260200180615160602a913960400191505060405180910390fd5b6000614ea261510b565b600080614eb3866000015186614f26565b90925090506000826003811115614ec657fe5b14614ee557506040805160208101909152600081529092509050614b13565b60408051602081019091529081526000969095509350505050565b51670de0b6b3a7640000900490565b6060614f1e8484600085614f65565b949350505050565b60008083614f3957506000905080614b13565b83830283858281614f4657fe5b0414614f5a57600260009250925050614b13565b600092509050614b13565b6060614f70856150d2565b614fc1576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b602083106150005780518252601f199092019160209182019101614fe1565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114615062576040519150601f19603f3d011682016040523d82523d6000602084013e615067565b606091505b5091509150811561507b579150614f1e9050565b80511561508b5780518082602001fd5b60405162461bcd60e51b8152602060048201818152865160248401528651879391928392604401919085019080838360008315614d3c578181015183820152602001614d24565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590614f1e575050151592915050565b604051806020016040528060008152509056fe000000000000000000000000ccf4429db6322d5c611ee964527d42e5d685dd6a536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a2646970667358221220b00e35e72a8c459b3d7b2c65cec4b381d84733f0e1a8539f8f6e26c074ebaddd64736f6c634300060c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000043229759e12efbe3e2a0fb0510b15e516d0464420000000000000000000000000bd1d668d8e83d14252f2e01d5873df77a6511f00000000000000000000000004bf5059065541a2b176500928e91fbfd0b121d070000000000000000000000005dae9b27313670663b34ac8bffd18825bb9df736
-----Decoded View---------------
Arg [0] : _governance (address): 0x43229759E12eFbe3e2A0fB0510B15e516d046442
Arg [1] : _strategist (address): 0x0bD1d668d8E83d14252F2e01D5873df77A6511f0
Arg [2] : _controller (address): 0x4bF5059065541A2B176500928e91FBfD0B121d07
Arg [3] : _timelock (address): 0x5DAe9B27313670663B34Ac8BfFD18825bB9Df736
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 00000000000000000000000043229759e12efbe3e2a0fb0510b15e516d046442
Arg [1] : 0000000000000000000000000bd1d668d8e83d14252f2e01d5873df77a6511f0
Arg [2] : 0000000000000000000000004bf5059065541a2b176500928e91fbfd0b121d07
Arg [3] : 0000000000000000000000005dae9b27313670663b34ac8bffd18825bb9df736
Deployed Bytecode Sourcemap
75379:17630:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76920:65;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59570:143;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;59570:143:0;-1:-1:-1;;;;;59570:143:0;;:::i;:::-;;80227:276;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;75710:73;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;75710:73:0;;;;;;;;;;;;;;75550;;;;;;;;;;;;;:::i;78755:206::-;;;;;;;;;;;;;:::i;56279:43::-;;;;;;;;;;;;;:::i;83030:117::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;83030:117:0;-1:-1:-1;;;;;83030:117:0;;:::i;58437:151::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;58437:151:0;;:::i;75790:74::-;;;;;;;;;;;;;:::i;75871:75::-;;;;;;;;;;;;;:::i;56353:33::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;78202:112;;;;;;;;;;;;;:::i;63329:1053::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;63329:1053:0;;;;;;;;;;;;;;;-1:-1:-1;;;63329:1053:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;63329:1053:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63329:1053:0;;-1:-1:-1;63329:1053:0;;-1:-1:-1;;;;;63329:1053:0:i;56562:19::-;;;;;;;;;;;;;:::i;57025:25::-;;;;;;;;;;;;;:::i;81615:195::-;;;;;;;;;;;;;:::i;80754:240::-;;;;;;;;;;;;;:::i;60682:1243::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;60682:1243:0;;:::i;83155:174::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;83155:174:0;;:::i;76187:43::-;;;;;;;;;;;;;:::i;76675:39::-;;;;;;;;;;;;;:::i;77054:::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;77054:39:0;-1:-1:-1;;;;;77054:39:0;;:::i;79341:323::-;;;;;;;;;;;;;:::i;75630:73::-;;;;;;;;;;;;;:::i;56588:::-;;;;;;;;;;;;;:::i;82909:113::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;82909:113:0;-1:-1:-1;;;;;82909:113:0;;:::i;79991:172::-;;;;;;;;;;;;;:::i;87944:1026::-;;;;;;;;;;;;;:::i;56857:73::-;;;;;;;;;;;;;:::i;76366:44::-;;;;;;;;;;;;;:::i;91098:190::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;91098:190:0;-1:-1:-1;;;;;91098:190:0;;:::i;56467:70::-;;;;;;;;;;;;;:::i;83337:158::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;83337:158:0;;:::i;56961:25::-;;;;;;;;;;;;;:::i;82655:215::-;;;;;;;;;;;;;:::i;82021:123::-;;;;;;;;;;;;;:::i;78615:132::-;;;;;;;;;;;;;:::i;75463:80::-;;;;;;;;;;;;;:::i;83503:175::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;83503:175:0;;;;:::i;58759:167::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;58759:167:0;;:::i;58212:113::-;;;;;;;;;;;;;:::i;76808:63::-;;;;;;;;;;;;;:::i;79672:311::-;;;;;;;;;;;;;:::i;78322:285::-;;;;;;;;;;;;;:::i;58596:155::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;58596:155:0;;:::i;82152:124::-;;;;;;;;;;;;;:::i;62476:440::-;;;;;;;;;;;;;:::i;56692:80::-;;;;;;;;;;;;;:::i;55955:37::-;;;;;;;;;;;;;:::i;59411:151::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;59411:151:0;-1:-1:-1;;;;;59411:151:0;;:::i;76115:65::-;;;;;;;;;;;;;:::i;59721:168::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;59721:168:0;;;;:::i;81818:195::-;;;;;;;;;;;;;:::i;82284:363::-;;;;;;;;;;;;;:::i;79105:228::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;79105:228:0;;:::i;59897:155::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;59897:155:0;-1:-1:-1;;;;;59897:155:0;;:::i;56393:67::-;;;;;;;;;;;;;:::i;59097:155::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;59097:155:0;-1:-1:-1;;;;;59097:155:0;;:::i;84448:216::-;;;;;;;;;;;;;:::i;83686:102::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;83686:102:0;-1:-1:-1;;;;;83686:102:0;;:::i;81405:202::-;;;;;;;;;;;;;:::i;56242:30::-;;;;;;;;;;;;;:::i;57101:72::-;;;;;;;;;;;;;:::i;59260:143::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;59260:143:0;-1:-1:-1;;;;;59260:143:0;;:::i;58015:118::-;;;;;;;;;;;;;:::i;58934:155::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;58934:155:0;-1:-1:-1;;;;;58934:155:0;;:::i;75953:85::-;;;;;;;;;;;;;:::i;56150:32::-;;;;;;;;;;;;;:::i;91382:1624::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;91382:1624:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;91382:1624:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;91382:1624:0;;;;;;;;;;-1:-1:-1;91382:1624:0;;-1:-1:-1;91382:1624:0;-1:-1:-1;91382:1624:0;:::i;56779:71::-;;;;;;;;;;;;;:::i;88978:313::-;;;;;;;;;;;;;:::i;57057:23::-;;;;;;;;;;;;;:::i;86509:1282::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;86509:1282:0;;:::i;85061:1176::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;85061:1176:0;;:::i;86245:150::-;;;;;;;;;;;;;:::i;56993:25::-;;;;;;;;;;;;;:::i;83954:486::-;;;;;;;;;;;;;:::i;76920:65::-;76964:21;;;-1:-1:-1;;;76964:21:0;;;;;;;;;;;;;;;;;;;;76920:65;:::o;59570:143::-;59650:10;;-1:-1:-1;;;;;59650:10:0;59636;:24;59628:48;;;;;-1:-1:-1;;;59628:48:0;;;;;;;;;;;;-1:-1:-1;;;59628:48:0;;;;;;;;;;;;;;;59687:7;:18;;-1:-1:-1;;;;;59687:18:0;;;;;-1:-1:-1;;;;;;59687:18:0;;;;;;;;;59570:143::o;80227:276::-;80274:7;80294:29;80326:26;:24;:26::i;:::-;80294:58;-1:-1:-1;80403:16:0;80422:47;80430:4;80440;:28;;;80422:17;:47::i;:::-;80403:66;-1:-1:-1;;;80227:276:0;;:::o;75710:73::-;75741:42;75710:73;:::o;75550:::-;75581:42;75550:73;:::o;78755:206::-;78810:7;78830:16;78849:17;:15;:17::i;:::-;78830:36;;78877:16;78896:17;:15;:17::i;:::-;78877:36;-1:-1:-1;78931:22:0;:8;78877:36;78931:12;:22::i;56279:43::-;56316:6;56279:43;:::o;83030:117::-;78091:10;;-1:-1:-1;;;;;78091:10:0;78077;:24;;:52;;-1:-1:-1;78119:10:0;;-1:-1:-1;;;;;78119:10:0;78105;:24;78077:52;78069:76;;;;;-1:-1:-1;;;78069:76:0;;;;;;;;;;;;-1:-1:-1;;;78069:76:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;83115:16:0::1;83134:5;83115:16:::0;;;:7:::1;:16;::::0;;;;:24;;-1:-1:-1;;83115:24:0::1;::::0;;83030:117::o;58437:151::-;58523:8;;-1:-1:-1;;;;;58523:8:0;58509:10;:22;58501:44;;;;;-1:-1:-1;;;58501:44:0;;;;;;;;;;;;-1:-1:-1;;;58501:44:0;;;;;;;;;;;;;;;58556:10;:24;58437:151::o;75790:74::-;-1:-1:-1;;;;;;;;;;;75790:74:0;:::o;75871:75::-;75904:42;75871:75;:::o;56353:33::-;;;;;;:::o;78202:112::-;78279:27;;;;;;;;;;;;-1:-1:-1;;;78279:27:0;;;;78202:112;:::o;63329:1053::-;63495:8;;63434:21;;-1:-1:-1;;;;;63495:8:0;63481:10;:22;63473:44;;;;;-1:-1:-1;;;63473:44:0;;;;;;;;;;;;-1:-1:-1;;;63473:44:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;63536:21:0;;63528:41;;;;;-1:-1:-1;;;63528:41:0;;;;;;;;;;;;-1:-1:-1;;;63528:41:0;;;;;;;;;;;;;;;63846:1;63826;63801:5;63795:12;63771:4;63764:5;63760:16;63734:7;63710:4;63703:5;63699:16;63668:194;63888:16;63938:4;63932:11;63920:23;;64055:4;64051:9;64044:4;64037;64031;64027:15;64023:26;64019:42;64009:8;64005:57;63982:4;63957:120;64108:4;64098:8;64091:22;64166:4;64163:1;64156:4;64146:8;64142:19;64127:44;64201:9;64194:17;64234:1;64229:135;;;;64187:177;;64229:135;64340:4;64333;64323:8;64319:19;64312:33;64187:177;;;;63636:739;;;;:::o;56562:19::-;;;-1:-1:-1;;;;;56562:19:0;;:::o;57025:25::-;;;-1:-1:-1;;;;;57025:25:0;;:::o;81615:195::-;81655:7;81675:16;81694:13;:11;:13::i;:::-;81675:32;;81718:16;81737:13;:11;:13::i;:::-;81718:32;-1:-1:-1;81770:32:0;81793:8;81770:18;81718:32;81783:4;81770:12;:18::i;:::-;:22;;:32::i;80754:240::-;80803:7;80823:21;80847:26;:24;:26::i;:::-;80823:50;;80891:95;80972:13;80892:74;80939:26;;80892:42;80929:4;80892:32;80920:3;80892:23;;:27;;:32;;;;:::i;:::-;:36;;:42::i;80891:95::-;80884:102;;;80754:240;:::o;60682:1243::-;60759:10;;-1:-1:-1;;;;;60759:10:0;60745;:24;60737:48;;;;;-1:-1:-1;;;60737:48:0;;;;;;;;;;;;-1:-1:-1;;;60737:48:0;;;;;;;;;;;;;;;60822:4;;60815:37;;;-1:-1:-1;;;60815:37:0;;60846:4;60815:37;;;;;;60796:16;;-1:-1:-1;;;;;60822:4:0;;60815:22;;:37;;;;;;;;;;;;;;60822:4;60815:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;60815:37:0;;-1:-1:-1;60867:18:0;;;60863:143;;;60912:36;60926:21;:7;60938:8;60926:11;:21::i;:::-;60912:13;:36::i;:::-;60902:46;-1:-1:-1;60973:21:0;60902:46;60985:8;60973:11;:21::i;:::-;60963:31;;60863:143;61022:15;61040:39;56316:6;61040:23;61052:10;;61040:7;:11;;:23;;;;:::i;:39::-;61022:57;;61090:20;61113:41;56227:6;61113:24;61125:11;;61113:7;:11;;:24;;;;:::i;:41::-;61171:14;;61090:64;;-1:-1:-1;61171:14:0;;:22;;:14;:22;61167:480;;;61273:25;;61326:48;61348:25;:7;61360:12;61348:11;:25::i;:::-;61326:21;:48::i;:::-;61272:102;;;;61389:51;61406:17;61425:14;61389:16;:51::i;:::-;61167:480;;;;;61514:10;;61502:33;;;-1:-1:-1;;;61502:33:0;;;;61476:69;;-1:-1:-1;;;;;61514:10:0;;61502:31;;:33;;;;;;;;;;;;;;61514:10;61502:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;61502:33:0;61483:4;;-1:-1:-1;;;;;61483:4:0;;61537:7;61476:25;:69::i;:::-;61598:10;;61586:34;;;-1:-1:-1;;;61586:34:0;;;;61560:75;;-1:-1:-1;;;;;61598:10:0;;61586:32;;:34;;;;;;;;;;;;;;61598:10;61586:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;61586:34:0;61567:4;;-1:-1:-1;;;;;61567:4:0;;61622:12;61560:25;:75::i;:::-;61696:10;;61723:4;;61684:45;;;-1:-1:-1;;;61684:45:0;;-1:-1:-1;;;;;61723:4:0;;;61684:45;;;;;;61667:14;;61696:10;;;;;61684:30;;:45;;;;;;;;;;;;;;;61696:10;61684:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;61684:45:0;;-1:-1:-1;;;;;;61748:20:0;;61740:39;;;;;-1:-1:-1;;;61740:39:0;;;;;;;;;;;;-1:-1:-1;;;61740:39:0;;;;;;;;;;;;;;;61844:73;61870:6;61878:38;61903:12;61878:20;:7;61890;61878:11;:20::i;:::-;:24;;:38::i;:::-;61851:4;;-1:-1:-1;;;;;61851:4:0;;61844:73;:25;:73::i;:::-;60682:1243;;;;;:::o;83155:174::-;78091:10;;-1:-1:-1;;;;;78091:10:0;78077;:24;;:52;;-1:-1:-1;78119:10:0;;-1:-1:-1;;;;;78119:10:0;78105;:24;78077:52;78069:76;;;;;-1:-1:-1;;;78069:76:0;;;;;;;;;;;;-1:-1:-1;;;78069:76:0;;;;;;;;;;;;;;;83271:23:::1;:50:::0;83155:174::o;76187:43::-;;;-1:-1:-1;;;76187:43:0;;;;;:::o;76675:39::-;;;;:::o;77054:::-;;;;;;;;;;;;;;;:::o;79341:323::-;79398:7;79418:17;79438:20;:18;:20::i;:::-;79418:40;;79519:21;79543:80;79557:65;79595:26;;79557:33;79585:4;79557:23;;:27;;:33;;;;:::i;:65::-;79543:9;;:13;:80::i;75630:73::-;75661:42;75630:73;:::o;56588:::-;56619:42;56588:73;:::o;82909:113::-;78091:10;;-1:-1:-1;;;;;78091:10:0;78077;:24;;:52;;-1:-1:-1;78119:10:0;;-1:-1:-1;;;;;78119:10:0;78105;:24;78077:52;78069:76;;;;;-1:-1:-1;;;78069:76:0;;;;;;;;;;;;-1:-1:-1;;;78069:76:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;82991:16:0::1;;::::0;;;:7:::1;:16;::::0;;;;:23;;-1:-1:-1;;82991:23:0::1;83010:4;82991:23;::::0;;82909:113::o;79991:172::-;80086:40;;;-1:-1:-1;;;80086:40:0;;-1:-1:-1;;;;;;;;;;;80086:40:0;;;;;;80042:7;;;;75501:42;;80086:33;;:40;;;;;;;;;;;;;75501:42;80086:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;80086:40:0;;;;-1:-1:-1;;79991:172:0;:::o;87944:1026::-;57834:10;57848:9;57834:23;;:68;;-1:-1:-1;57892:10:0;;-1:-1:-1;;;;;57892:10:0;57878;:24;57834:68;:113;;;-1:-1:-1;57937:10:0;;-1:-1:-1;;;;;57937:10:0;57923;:24;57834:113;57812:146;;;;;;88032:16:::1;::::0;;88046:1:::1;88032:16:::0;;;;;::::1;::::0;;;88005:24:::1;::::0;88032:16:::1;::::0;;::::1;::::0;;::::1;::::0;::::1;;::::0;-1:-1:-1;88032:16:0::1;88005:43;;-1:-1:-1::0;;;;;;;;;;;88059:7:0::1;88067:1;88059:10;;;;;;;;-1:-1:-1::0;;;;;88059:18:0;;::::1;:10;::::0;;::::1;::::0;;;;;;:18;88090:59:::1;::::0;;-1:-1:-1;;;88090:59:0;;88134:4:::1;88090:59;::::0;::::1;::::0;;;;;;;;;;;;;;;;;75501:42:::1;::::0;88090:35:::1;::::0;88134:4;;88141:7;;88090:59;;;;;;;;::::1;::::0;::::1;::::0;;;-1:-1:-1;88090:59:0::1;;;;;;;::::0;;::::1;::::0;;;::::1;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;88176:37:0::1;::::0;;-1:-1:-1;;;88176:37:0;;88207:4:::1;88176:37;::::0;::::1;::::0;;;88160:13:::1;::::0;-1:-1:-1;75741:42:0::1;::::0;-1:-1:-1;88176:22:0::1;::::0;:37;;;;;::::1;::::0;;;;;;;;;75741:42;88176:37;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;88176:37:0;;-1:-1:-1;88228:9:0;;88224:73:::1;;88273:4;::::0;88254:31:::1;::::0;75741:42:::1;::::0;-1:-1:-1;;;;;88273:4:0::1;88279:5:::0;88254:12:::1;:31::i;:::-;88332:4;::::0;88325:37:::1;::::0;;-1:-1:-1;;;88325:37:0;;88356:4:::1;88325:37;::::0;::::1;::::0;;;88309:13:::1;::::0;-1:-1:-1;;;;;88332:4:0::1;::::0;88325:22:::1;::::0;:37;;;;;::::1;::::0;;;;;;;;88332:4;88325:37;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;88325:37:0;88373:22:::1;88408:14:::0;;88325:37;;-1:-1:-1;88373:22:0;88398:45:::1;::::0;56040:6:::1;::::0;88398:25:::1;::::0;88325:37;;88398:9:::1;:25::i;:45::-;88460:14;::::0;88373:70;;-1:-1:-1;88460:14:0::1;;:22;;:14:::0;:22:::1;:44:::0;::::1;;;;88503:1;88486:14;:18;88460:44;88456:400;;;88538:4;::::0;88521:38:::1;::::0;-1:-1:-1;;;;;88538:4:0::1;88544:14:::0;88521:16:::1;:38::i;:::-;88456:400;;;88637:9:::0;;88633:212:::1;;88759:10;::::0;88747:34:::1;::::0;;-1:-1:-1;;;88747:34:0;;;;88721:108:::1;::::0;-1:-1:-1;;;;;88759:10:0::1;::::0;88747:32:::1;::::0;:34:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;88759:10;88747:34;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;88747:34:0;88793:14:::1;::::0;88783:45:::1;::::0;56040:6:::1;::::0;88783:25:::1;::::0;:5;;:9:::1;:25::i;88721:108::-;88916:9:::0;;88912:51:::1;;88942:9;:7;:9::i;:::-;57969:1;;;;87944:1026::o:0;56857:73::-;;;-1:-1:-1;;;;;56857:73:0;;:::o;76366:44::-;;;;:::o;91098:190::-;91158:15;-1:-1:-1;;;;;;;;;;;;;;;;91194:24:0;;;;91186:44;;;;;-1:-1:-1;;;91186:44:0;;;;;;;;;;;;-1:-1:-1;;;91186:44:0;;;;;;;;;;;;;;;91251:29;91273:6;91251:21;:29::i;:::-;91241:39;91098:190;-1:-1:-1;;91098:190:0:o;56467:70::-;;;-1:-1:-1;;;;;56467:70:0;;:::o;83337:158::-;78091:10;;-1:-1:-1;;;;;78091:10:0;78077;:24;;:52;;-1:-1:-1;78119:10:0;;-1:-1:-1;;;;;78119:10:0;78105;:24;78077:52;78069:76;;;;;-1:-1:-1;;;78069:76:0;;;;;;;;;;;;-1:-1:-1;;;78069:76:0;;;;;;;;;;;;;;;83445:19:::1;:42:::0;83337:158::o;56961:25::-;;;-1:-1:-1;;;;;56961:25:0;;:::o;82655:215::-;82701:7;82721:16;82740:13;:11;:13::i;:::-;82721:32;;82764:16;82783:13;:11;:13::i;:::-;82764:32;-1:-1:-1;82816:46:0;82839:22;:8;82764:32;82839:12;:22::i;:::-;82816:18;:8;82829:4;82816:12;:18::i;82021:123::-;82087:49;;;-1:-1:-1;;;82087:49:0;;82130:4;82087:49;;;;;;82060:7;;-1:-1:-1;;;;;;;;;;;75822:42:0;82087:34;;:49;;;;;;;;;;;;;;;82060:7;75822:42;82087:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;82087:49:0;;-1:-1:-1;82021:123:0;:::o;78615:132::-;78690:49;;;-1:-1:-1;;;78690:49:0;;78733:4;78690:49;;;;;;78663:7;;-1:-1:-1;;;;;;;;;;;75822:42:0;78690:34;;:49;;;;;;;;;;;;;;;75822:42;78690:49;;;;;;;;;;;;;;;;;;;;;;;;;;75463:80;75501:42;75463:80;:::o;83503:175::-;78091:10;;-1:-1:-1;;;;;78091:10:0;78077;:24;;:52;;-1:-1:-1;78119:10:0;;-1:-1:-1;;;;;78119:10:0;78105;:24;78077:52;78069:76;;;;;-1:-1:-1;;;78069:76:0;;;;;;;;;;;;-1:-1:-1;;;78069:76:0;;;;;;;;;;;;;;;83618:24:::1;:52:::0;;;::::1;;-1:-1:-1::0;;;83618:52:0::1;-1:-1:-1::0;;;;83618:52:0;;::::1;::::0;;;::::1;::::0;;83503:175::o;58759:167::-;58853:8;;-1:-1:-1;;;;;58853:8:0;58839:10;:22;58831:44;;;;;-1:-1:-1;;;58831:44:0;;;;;;;;;;;;-1:-1:-1;;;58831:44:0;;;;;;;;;;;;;;;58886:14;:32;58759:167::o;58212:113::-;58254:7;58281:36;58301:15;:13;:15::i;:::-;58281;:13;:15::i;:::-;:19;;:36::i;:::-;58274:43;;58212:113;:::o;76808:63::-;76850:21;;;-1:-1:-1;;;76850:21:0;;;;;;;;;;;;;;;;;;;;76808:63;:::o;79672:311::-;79725:7;79745:17;79765:20;:18;:20::i;:::-;79745:40;;79846:21;79870:72;79884:57;79918:22;;79884:29;79908:4;79884:19;;:23;;:29;;;;:::i;78322:285::-;78370:7;78393:17;78414:20;-1:-1:-1;;;;;;;;;;;;;;;;78438:33:0;;78480:4;78438:48;;;;;;;;;;;;;-1:-1:-1;;;;;78438:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;78438:48:0;;;;;;;;;;;78535:29;;;;;;;;;;78438:48;;-1:-1:-1;78438:48:0;;-1:-1:-1;78502:11:0;;78517:59;;78438:48;78517:17;:59::i;:::-;78499:77;-1:-1:-1;;;;;78322:285:0;:::o;58596:155::-;58684:8;;-1:-1:-1;;;;;58684:8:0;58670:10;:22;58662:44;;;;;-1:-1:-1;;;58662:44:0;;;;;;;;;;;;-1:-1:-1;;;58662:44:0;;;;;;;;;;;;;;;58717:11;:26;58596:155::o;82152:124::-;82218:50;;;-1:-1:-1;;;82218:50:0;;82262:4;82218:50;;;;;;82191:7;;-1:-1:-1;;;;;;;;;;;75822:42:0;82218:35;;:50;;;;;;;;;;;;;;;82191:7;75822:42;82218:50;;;;;;;;;;62476:440;62567:10;;62517:15;;-1:-1:-1;;;;;62567:10:0;62553;:24;62545:48;;;;;-1:-1:-1;;;62545:48:0;;;;;;;;;;;;-1:-1:-1;;;62545:48:0;;;;;;;;;;;;;;;62604:14;:12;:14::i;:::-;62648:4;;62641:37;;;-1:-1:-1;;;62641:37:0;;62672:4;62641:37;;;;;;-1:-1:-1;;;;;62648:4:0;;;;62641:22;;:37;;;;;;;;;;;;;;;62648:4;62641:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;62641:37:0;62720:10;;62747:4;;62708:45;;;-1:-1:-1;;;62708:45:0;;-1:-1:-1;;;;;62747:4:0;;;62708:45;;;;;;62641:37;;-1:-1:-1;62691:14:0;;62720:10;;;;;62708:30;;:45;;;;;62641:37;;62708:45;;;;;;;62720:10;62708:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;62708:45:0;;-1:-1:-1;;;;;;62772:20:0;;62764:39;;;;;-1:-1:-1;;;62764:39:0;;;;;;;;;;;;-1:-1:-1;;;62764:39:0;;;;;;;;;;;;;;;62873:4;;62866:42;;-1:-1:-1;;;;;62873:4:0;62892:6;62900:7;62866:25;:42::i;:::-;62476:440;;:::o;56692:80::-;56730:42;56692:80;:::o;55955:37::-;;;;:::o;59411:151::-;59497:8;;-1:-1:-1;;;;;59497:8:0;59483:10;:22;59475:44;;;;;-1:-1:-1;;;59475:44:0;;;;;;;;;;;;-1:-1:-1;;;59475:44:0;;;;;;;;;;;;;;;59530:10;:24;;-1:-1:-1;;;;;;59530:24:0;-1:-1:-1;;;;;59530:24:0;;;;;;;;;;59411:151::o;76115:65::-;;;-1:-1:-1;;;;;76115:65:0;;:::o;59721:168::-;59812:10;;-1:-1:-1;;;;;59812:10:0;59798;:24;59790:48;;;;;-1:-1:-1;;;59790:48:0;;;;;;;;;;;;-1:-1:-1;;;59790:48:0;;;;;;;;;;;;;;;59849:14;:32;;-1:-1:-1;;59849:32:0;;;;;;;;;;59721:168::o;81818:195::-;81868:7;81888:16;81907:13;:11;:13::i;:::-;81888:32;;81931:16;81950:13;:11;:13::i;82284:363::-;82325:7;82345:16;82364:13;:11;:13::i;:::-;82345:32;;82388:16;82407:13;:11;:13::i;:::-;82457:40;;;-1:-1:-1;;;82457:40:0;;-1:-1:-1;;;;;;;;;;;82457:40:0;;;;;;82388:32;;-1:-1:-1;82436:17:0;;75501:42;;82457:33;;:40;;;;;;;;;;;75501:42;82457:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;82457:40:0;;;;-1:-1:-1;82571:68:0;82633:5;82571:57;82623:4;82571:47;82609:8;82571:33;82599:4;82571:57;:8;82457:40;82571:12;:23::i;:68::-;82564:75;;;;;82284:363;:::o;79105:228::-;79210:7;79235:16;79254;:14;:16::i;:::-;79235:35;-1:-1:-1;79288:37:0;79320:4;79288:27;:13;79235:35;79288:17;:27::i;:37::-;79281:44;;;79105:228;;;;:::o;59897:155::-;59983:10;;-1:-1:-1;;;;;59983:10:0;59969;:24;59961:48;;;;;-1:-1:-1;;;59961:48:0;;;;;;;;;;;;-1:-1:-1;;;59961:48:0;;;;;;;;;;;;;;;60020:10;:24;;-1:-1:-1;;;;;;60020:24:0;-1:-1:-1;;;;;60020:24:0;;;;;;;;;;59897:155::o;56393:67::-;;;;;;-1:-1:-1;;;;;56393:67:0;;:::o;59097:155::-;59183:10;;-1:-1:-1;;;;;59183:10:0;59169;:24;59161:48;;;;;-1:-1:-1;;;59161:48:0;;;;;;;;;;;;-1:-1:-1;;;59161:48:0;;;;;;;;;;;;;;;59220:10;:24;;-1:-1:-1;;;;;;59220:24:0;-1:-1:-1;;;;;59220:24:0;;;;;;;;;;59097:155::o;84448:216::-;84491:25;84519:24;:22;:24::i;:::-;84491:52;;84554:19;84576:43;84601:17;84576:24;:43::i;:::-;84554:65;;84630:26;84644:11;84630:13;:26::i;:::-;84448:216;;:::o;83686:102::-;78091:10;;-1:-1:-1;;;;;78091:10:0;78077;:24;;:52;;-1:-1:-1;78119:10:0;;-1:-1:-1;;;;;78119:10:0;78105;:24;78077:52;78069:76;;;;;-1:-1:-1;;;78069:76:0;;;;;;;;;;;;-1:-1:-1;;;78069:76:0;;;;;;;;;;;;;;;83766:5:::1;:14:::0;;-1:-1:-1;;;;;;83766:14:0::1;-1:-1:-1::0;;;;;83766:14:0;;;::::1;::::0;;;::::1;::::0;;83686:102::o;81405:202::-;81493:79;;;-1:-1:-1;;;81493:79:0;;75741:42;81493:79;;;;75501:42;81493:79;;;;81566:4;81493:79;;;;;;81447:7;;;;75581:42;;81493:45;;:79;;;;;;;;;;;;;;81447:7;75581:42;81493:79;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;81493:79:0;;;;-1:-1:-1;;81405:202:0;:::o;56242:30::-;;;;:::o;57101:72::-;;;-1:-1:-1;;;;;57101:72:0;;:::o;59260:143::-;59342:8;;-1:-1:-1;;;;;59342:8:0;59328:10;:22;59320:44;;;;;-1:-1:-1;;;59320:44:0;;;;;;;;;;;;-1:-1:-1;;;59320:44:0;;;;;;;;;;;;;;;59375:8;:20;;-1:-1:-1;;;;;;59375:20:0;-1:-1:-1;;;;;59375:20:0;;;;;;;;;;59260:143::o;58015:118::-;58095:4;;58088:37;;;-1:-1:-1;;;58088:37:0;;58119:4;58088:37;;;;;;58061:7;;-1:-1:-1;;;;;58095:4:0;;58088:22;;:37;;;;;;;;;;;;;;58095:4;58088:37;;;;;;;;;;58934:155;59020:10;;-1:-1:-1;;;;;59020:10:0;59006;:24;58998:48;;;;;-1:-1:-1;;;58998:48:0;;;;;;;;;;;;-1:-1:-1;;;58998:48:0;;;;;;;;;;;;;;;59057:10;:24;;-1:-1:-1;;;;;;59057:24:0;-1:-1:-1;;;;;59057:24:0;;;;;;;;;;58934:155::o;75953:85::-;75995:42;75953:85;:::o;56150:32::-;;;;:::o;91382:1624::-;91520:24;;-1:-1:-1;;;91520:24:0;;;;:47;;;;-1:-1:-1;91548:5:0;;-1:-1:-1;;;;;91548:5:0;:19;;91520:47;91512:72;;;;;-1:-1:-1;;;91512:72:0;;;;;;;;;;;;-1:-1:-1;;;91512:72:0;;;;;;;;;;;;;;;91613:4;;-1:-1:-1;;;;;91603:14:0;;;91613:4;;91603:14;91595:46;;;;;-1:-1:-1;;;91595:46:0;;;;;;;;;;;;-1:-1:-1;;;91595:46:0;;;;;;;;;;;;;;;91679:7;91660:15;:13;:15::i;:::-;:26;;91652:58;;;;;-1:-1:-1;;;91652:58:0;;;;;;;;;;;;-1:-1:-1;;;91652:58:0;;;;;;;;;;;;;;;91725:13;91741:21;:7;91753:8;91741:11;:21::i;:::-;91725:37;;91773:22;91798:5;;91773:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;91838:5:0;;91818:30;;;-1:-1:-1;;;91818:30:0;;-1:-1:-1;;;;;91838:5:0;;;91818:30;;;;;;;;;;;91773;;-1:-1:-1;75995:42:0;;91818:11;;-1:-1:-1;91818:30:0;;;;;-1:-1:-1;91818:30:0;;-1:-1:-1;91818:30:0;;;;;;;;;;75995:42;91818:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;91879:5:0;;91859:40;;;-1:-1:-1;;;91859:40:0;;-1:-1:-1;;;;;91879:5:0;;;91859:40;;;;-1:-1:-1;;91859:40:0;;;;;75995:42;;91859:11;;:40;;;;;91818:30;;91859:40;;;;;;;-1:-1:-1;75995:42:0;91859:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;91962:12:0;;:9;;91972:1;;91962:12;;;;;;;;;-1:-1:-1;;;;;;91962:12:0;-1:-1:-1;;;91962:20:0;91958:924;;;91998:9;:7;:9::i;:::-;92049:5;92030:15;:13;:15::i;:::-;:24;;92022:58;;;;;-1:-1:-1;;;92022:58:0;;;;;;;;;;;;-1:-1:-1;;;92022:58:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;92103:21:0;;92125:5;92103:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;92103:28:0;:33;92095:66;;;;;-1:-1:-1;;;92095:66:0;;;;;;;;;;;;-1:-1:-1;;;92095:66:0;;;;;;;;;;;;;;;92181:64;92199:7;92208:8;92218:5;;92231;;;;;;;;;-1:-1:-1;;;;;92231:5:0;-1:-1:-1;;;;;92225:17:0;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;92225:19:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;92225:19:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;92225:19:0;;;;;;-1:-1:-1;92225:19:0;;;;;;;;;;-1:-1:-1;92225:19:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92181:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;92181:64:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;92181:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91958:924;;;92321:9;92331:1;92321:12;;;;;;;;;;;;;-1:-1:-1;;;;;;92321:12:0;-1:-1:-1;;;92321:20:0;92318:564;;;92357:34;75661:42;-1:-1:-1;;;;;;;;;;;92389:1:0;92357:24;:34::i;:::-;92406:40;75661:42;-1:-1:-1;;;;;;;;;;;92438:7:0;92406:24;:40::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;92469:26:0;;92496:7;92469:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;92469:35:0;:40;92461:74;;;;;-1:-1:-1;;;92461:74:0;;;;;;;;;;;;-1:-1:-1;;;92461:74:0;;;;;;;;;;;;;;;92660:5;92641:15;:13;:15::i;:::-;:24;;92633:58;;;;;-1:-1:-1;;;92633:58:0;;;;;;;;;;;;-1:-1:-1;;;92633:58:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;92714:31:0;;92746:5;92714:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;92714:38:0;:43;92706:78;;;;;-1:-1:-1;;;92706:78:0;;;;;;;;;;;;-1:-1:-1;;;92706:78:0;;;;;;;;;;;;;;;92804:66;92824:7;92833:8;92843:5;;92856;;;;;;;;;-1:-1:-1;;;;;92856:5:0;-1:-1:-1;;;;;92850:17:0;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;92850:19:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;92850:19:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;92850:19:0;;;;;;-1:-1:-1;92850:19:0;;;;;;;;;;-1:-1:-1;92850:19:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92804:66;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;92804:66:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;92804:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92318:564;92924:5;92905:15;:13;:15::i;:::-;:24;;92897:55;;;;;-1:-1:-1;;;92897:55:0;;;;;;;;;;;;-1:-1:-1;;;92897:55:0;;;;;;;;;;;;;;;92970:4;;92985:5;;92963:35;;;-1:-1:-1;;;92963:35:0;;-1:-1:-1;;;;;92985:5:0;;;92963:35;;;;;;;;;;;;92970:4;;;;;92963:21;;:35;;;;;;;;;;;;;;92970:4;;92963:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;91382:1624:0:o;56779:71::-;;;-1:-1:-1;;;;;56779:71:0;;:::o;88978:313::-;89047:4;;89040:37;;;-1:-1:-1;;;89040:37:0;;89071:4;89040:37;;;;;;89024:13;;-1:-1:-1;;;;;89047:4:0;;89040:22;;:37;;;;;;;;;;;;;;89047:4;89040:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;89040:37:0;;-1:-1:-1;89092:9:0;;89088:196;;89125:4;;89118:34;;-1:-1:-1;;;;;89125:4:0;-1:-1:-1;;;;;;;;;;;89150:1:0;89118:24;:34::i;:::-;89174:4;;89167:38;;-1:-1:-1;;;;;89174:4:0;-1:-1:-1;;;;;;;;;;;89199:5:0;89167:24;:38::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;89228:19:0;;89248:5;89228:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;89228:26:0;:31;89220:52;;;;;-1:-1:-1;;;89220:52:0;;;;;;;;;;;;-1:-1:-1;;;89220:52:0;;;;;;;;;;;;;;;88978:313;:::o;57057:23::-;;;-1:-1:-1;;;;;57057:23:0;;:::o;86509:1282::-;77807:10;77799:19;;;;:7;:19;;;;;;;;;:67;;-1:-1:-1;77839:10:0;77861:4;77839:27;77799:67;:112;;;-1:-1:-1;77901:10:0;;-1:-1:-1;;;;;77901:10:0;77887;:24;77799:112;:157;;;-1:-1:-1;77946:10:0;;-1:-1:-1;;;;;77946:10:0;77932;:24;77799:157;77777:215;;;;;-1:-1:-1;;;77777:215:0;;;;;;;;;;;;-1:-1:-1;;;77777:215:0;;;;;;;;;;;;;;;86587:25:::1;86615:24;:22;:24::i;:::-;86587:52;;86650:16;86669:13;:11;:13::i;:::-;86650:32;;86732:17;86715:13;:34;;:63;;;;;86770:8;86753:13;:25;;86715:63;86693:124;;;::::0;;-1:-1:-1;;;86693:124:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;86693:124:0;;;;;;;;;;;;;::::1;;86917:23;86943:15;:13;:15::i;:::-;86917:41:::0;-1:-1:-1;86969:12:0::1;86984:27;:8:::0;86997:13;86984:12:::1;:27::i;:::-;86969:42;;87037:1;87030:4;:8;:47;;;;;87042:35;87072:4;87042:29;:35::i;:::-;87026:758;;;87100:5;::::0;76964:21:::1;::::0;;-1:-1:-1;;;76964:21:0::1;::::0;;::::1;::::0;;;;;;;;;87100:5;76964:21;;;;;;;;;;-1:-1:-1;;;87093:65:0;;;87125:4:::1;87093:65:::0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;87100:5:0;;::::1;::::0;87093:23:::1;::::0;87125:4;;87132;;87093:65;;;;;;;::::1;::::0;;;;87100:5:::1;87093:65;;;;;;;::::0;;::::1;::::0;;;::::1;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;87026:758;;;87248:13:::0;87216:29:::1;:8:::0;87229:15;87216:12:::1;:29::i;:::-;:45;87212:137;;;87303:27;:8:::0;87316:13;87303:12:::1;:27::i;:::-;87285:45;;87212:137;-1:-1:-1::0;;;;;;;;;;;;;;;;87376:31:0::1;;87408:15;87376:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;87376:48:0;:53;87368:90:::1;;;::::0;;-1:-1:-1;;;87368:90:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;87476:34;75661:42;-1:-1:-1::0;;;;;;;;;;;87508:1:0::1;87476:24;:34::i;:::-;87528:48;75661:42;-1:-1:-1::0;;;;;;;;;;;87560:15:0;87528:24:::1;:48::i;:::-;-1:-1:-1::0;;;;;;;;;;;;;;;;87602:26:0::1;;87629:15;87602:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;87602:43:0;:48;87594:67:::1;;;::::0;;-1:-1:-1;;;87594:67:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;87594:67:0;;;;;;;;;;;;;::::1;;87692:29;:8:::0;87705:15;87692:12:::1;:29::i;:::-;87681:40;;87756:13;87745:8;:24;87191:580;;78003:1;;;;86509:1282:::0;:::o;85061:1176::-;77807:10;77799:19;;;;:7;:19;;;;;;;;;:67;;-1:-1:-1;77839:10:0;77861:4;77839:27;77799:67;:112;;;-1:-1:-1;77901:10:0;;-1:-1:-1;;;;;77901:10:0;77887;:24;77799:112;:157;;;-1:-1:-1;77946:10:0;;-1:-1:-1;;;;;77946:10:0;77932;:24;77799:157;77777:215;;;;;-1:-1:-1;;;77777:215:0;;;;;;;;;;;;-1:-1:-1;;;77777:215:0;;;;;;;;;;;;;;;85139:16:::1;85158;:14;:16::i;:::-;85139:35;;85185:25;85213:24;:22;:24::i;:::-;85185:52;;85287:17;85270:13;:34;;:113;;;;-1:-1:-1::0;85342:41:0::1;85378:4;85342:31;:17:::0;85364:8;85342:21:::1;:31::i;:41::-;85325:13;:58;;85270:113;85248:172;;;::::0;;-1:-1:-1;;;85248:172:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;85248:172:0;;;;;;;;;;;;;::::1;;85515:24;85550:16:::0;85569:13:::1;:11;:13::i;:::-;85550:32:::0;-1:-1:-1;85593:12:0::1;85608:27;:13:::0;85550:32;85608:17:::1;:27::i;:::-;85593:42;;85661:1;85654:4;:8;:47;;;;;85666:35;85696:4;85666:29;:35::i;:::-;85650:580;;;85724:5;::::0;76850:21:::1;::::0;;-1:-1:-1;;;76850:21:0::1;::::0;;::::1;::::0;;;;;;;;;85724:5;76850:21;;;;;;;;;;-1:-1:-1;;;85717:63:0;;;85749:4:::1;85717:63:::0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;85724:5:0;;::::1;::::0;85717:23:::1;::::0;85749:4;;85756;;85717:63;;;;;;;::::1;::::0;;;;85724:5:::1;85717:63;;;;;;;::::0;;::::1;::::0;;;::::1;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;85650:580;;;85830:13;85819:8;:24;85812:406;;;85882:15;:13;:15::i;:::-;85863:34:::0;-1:-1:-1;85954:13:0;85921:30:::1;:8:::0;85863:34;85921:12:::1;:30::i;:::-;:46;85917:139;;;86010:27;:13:::0;86028:8;86010:17:::1;:27::i;:::-;85991:46;;85917:139;-1:-1:-1::0;;;;;;;;;;;;;;;;86075:21:0::1;;86097:16;86075:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;86132:9:0::1;::::0;-1:-1:-1;86132:7:0::1;:9::i;:::-;86172:30;:8:::0;86185:16;86172:12:::1;:30::i;:::-;86161:41;;85812:406;;;78003:1;;;;;85061:1176:::0;:::o;86245:150::-;86290:25;86318:24;:22;:24::i;:::-;86290:52;;86353:34;86369:17;86353:15;:34::i;56993:25::-;;;-1:-1:-1;;;;;56993:25:0;;:::o;83954:486::-;83986:4;84003:17;84023:14;:12;:14::i;:::-;84003:34;;84048:25;84076:22;:20;:22::i;:::-;84048:50;;84157:17;84145:9;:29;84141:267;;;84191:25;84219:24;:22;:24::i;:::-;84191:52;;84258:19;84280:43;84305:17;84280:24;:43::i;:::-;84258:65;;84340:28;84356:11;84340:15;:28::i;:::-;84392:4;84385:11;;;;;;;;84141:267;84427:5;84420:12;;;;83954:486;:::o;3170:132::-;3228:7;3255:39;3259:1;3262;3255:39;;;;;;;;;;;;;;;;;:3;:39::i;:::-;3248:46;3170:132;-1:-1:-1;;;3170:132:0:o;1333:136::-;1391:7;1418:43;1422:1;1425;1418:43;;;;;;;;;;;;;;;;;:3;:43::i;2223:471::-;2281:7;2526:6;2522:47;;-1:-1:-1;2556:1:0;2549:8;;2522:47;2593:5;;;2597:1;2593;:5;:1;2617:5;;;;;:10;2609:56;;;;-1:-1:-1;;;2609:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89299:1716;89393:7;89469:16;89488:15;:13;:15::i;:::-;89469:34;;89514:15;89532:7;89514:25;;89637:7;-1:-1:-1;;;;;;;;;;;;;;;;89609:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;89609:24:0;:35;;89601:63;;;;;-1:-1:-1;;;89601:63:0;;;;;;;;;;;;-1:-1:-1;;;89601:63:0;;;;;;;;;;;;;;;89734:16;89753:13;:11;:13::i;:::-;89734:32;;89777:16;89796:13;:11;:13::i;:::-;89777:32;;89820:19;89842:20;:18;:20::i;:::-;89820:42;-1:-1:-1;89873:24:0;89900:34;89929:4;89900:24;:7;89820:42;89900:11;:24::i;:34::-;89873:61;;89945:17;90111:8;90092:16;:27;90088:475;;;90151:69;90181:38;90194:24;:22;:24::i;:::-;90181:8;;:12;:38::i;:::-;90151:29;:69::i;:::-;90136:84;;90235:4;-1:-1:-1;;;;;90235:20:0;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90088:475;;;90437:47;90467:16;90437:29;:47::i;:::-;90422:62;-1:-1:-1;90499:4:0;:20;90520:30;:8;90533:16;90520:12;:30::i;:::-;90499:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90088:475;-1:-1:-1;;;;;;;;;;;90614:31:0;90646:12;:124;;90763:7;90646:124;;;90740:5;;90733:26;;;-1:-1:-1;;;90733:26:0;;;;90660:100;;-1:-1:-1;;;;;90740:5:0;;90733:24;;:26;;;;;;;;;;;;;;90740:5;90733:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;90733:26:0;90710:5;;90703:23;;;-1:-1:-1;;;90703:23:0;;;;90660:68;;90672:55;;-1:-1:-1;;;;;90710:5:0;;;;90703:21;;:23;;;;;90733:26;;90703:23;;;;;;;;90710:5;90703:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;90703:23:0;90679:5;;90672:26;;;-1:-1:-1;;;90672:26:0;;;;-1:-1:-1;;;;;90679:5:0;;;;90672:24;;:26;;;;;90703:23;;90672:26;;;;;;;;90679:5;90672:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;90672:26:0;;:30;:55::i;:::-;90660:7;;:11;:68::i;:100::-;90614:157;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;90614:157:0;:162;90606:214;;;;;-1:-1:-1;;;90606:214:0;;;;;;;;;;;;-1:-1:-1;;;90606:214:0;;;;;;;;;;;;;;;90897:17;90917:15;:13;:15::i;:::-;90897:35;-1:-1:-1;90955:23:0;90897:35;90969:8;90955:13;:23::i;:::-;90943:35;89299:1716;-1:-1:-1;;;;;;;;;;89299:1716:0:o;869:181::-;927:7;959:5;;;983:6;;;;975:46;;;;;-1:-1:-1;;;975:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;87799:137;75661:42;87799:137;:::o;61975:425::-;62076:14;;;;:22;;:14;:22;62072:321;;;62147:7;;62115:56;;62128:17;;62147:7;;;-1:-1:-1;;;;;62147:7:0;62156:14;62115:12;:56::i;:::-;62213:7;;62206:40;;;-1:-1:-1;;;62206:40:0;;62240:4;62206:40;;;;;;-1:-1:-1;;62213:7:0;;;-1:-1:-1;;;;;62213:7:0;;62206:25;;:40;;;;;;;;;;;;;;62213:7;62206:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;62206:40:0;62290:10;;62268:7;;62206:40;;-1:-1:-1;62261:51:0;;62290:10;62268:7;;-1:-1:-1;;;;;62268:7:0;;;;62290:10;62206:40;62261:28;:51::i;:::-;62339:10;;;62327:54;;;-1:-1:-1;;;62327:54:0;;;;;;;;;-1:-1:-1;;;;;62339:10:0;;;;62327:43;;:54;;;;;62339:10;;62327:54;;;;;;;62339:10;;62327:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62072:321;61975:425;;:::o;26603:177::-;26713:58;;;-1:-1:-1;;;;;26713:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;26713:58:0;-1:-1:-1;;;26713:58:0;;;26686:86;;26706:5;;26686:19;:86::i;:::-;26603:177;;;:::o;64427:1537::-;-1:-1:-1;;;;;64556:17:0;;64548:26;;;;;;64643:12;;64617:42;;-1:-1:-1;;;;;64617:25:0;;;;64643:12;;64617:25;:42::i;:::-;64696:12;;64670:48;;-1:-1:-1;;;;;64670:25:0;;;;64696:12;64710:7;64670:25;:48::i;:::-;64776:7;;64731:21;;-1:-1:-1;;;;;64769:14:0;;;64776:7;;;;;64769:14;:40;;;;-1:-1:-1;64787:14:0;;;;:22;;:14;:22;64769:40;64765:1003;;;-1:-1:-1;;;;;64830:20:0;;56730:42;64830:20;64826:575;;;64877:16;;;64891:1;64877:16;;;;;;;;;;;;;;;;;;;;-1:-1:-1;64877:16:0;64870:23;;64922:5;64912:4;64917:1;64912:7;;;;;;;;;;;;;:15;-1:-1:-1;;;;;64912:15:0;;;-1:-1:-1;;;;;64912:15:0;;;;;64956:3;64946:4;64951:1;64946:7;;;;;;;;;;;;;:13;-1:-1:-1;;;;;64946:13:0;;;-1:-1:-1;;;;;64946:13:0;;;;;64826:575;;;64998:13;;-1:-1:-1;;;;;64989:22:0;;;64998:13;;64989:22;;:46;;-1:-1:-1;65024:11:0;;-1:-1:-1;;;;;65015:20:0;;;65024:11;;65015:20;64989:46;64986:415;;;65062:16;;;65076:1;65062:16;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65062:16:0;65055:23;;65107:5;65097:4;65102:1;65097:7;;;;;;;;;;;;;:15;-1:-1:-1;;;;;65097:15:0;;;-1:-1:-1;;;;;65097:15:0;;;;;56619:42;65131:4;65136:1;65131:7;;;;;;;;;;;;;:14;-1:-1:-1;;;;;65131:14:0;;;-1:-1:-1;;;;;65131:14:0;;;;;56730:42;65164:4;65169:1;65164:7;;;;;;;;;;;;;:21;-1:-1:-1;;;;;65164:21:0;;;-1:-1:-1;;;;;65164:21:0;;;;;65214:3;65204:4;65209:1;65204:7;;;;;;;64986:415;65263:16;;;65277:1;65263:16;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65263:16:0;65256:23;;65308:5;65298:4;65303:1;65298:7;;;;;;;;;;;;;:15;-1:-1:-1;;;;;65298:15:0;;;-1:-1:-1;;;;;65298:15:0;;;;;56730:42;65332:4;65337:1;65332:7;;;;;;;;;;;;;:21;-1:-1:-1;;;;;65332:21:0;;;-1:-1:-1;;;;;65332:21:0;;;;;65382:3;65372:4;65377:1;65372:7;;;;;;;;;;;;;:13;-1:-1:-1;;;;;65372:13:0;;;-1:-1:-1;;;;;65372:13:0;;;;;64986:415;64765:1003;;;-1:-1:-1;;;;;65438:13:0;;56619:42;65438:13;;:28;;-1:-1:-1;;;;;;65455:11:0;;56619:42;65455:11;65438:28;65434:321;;;65494:16;;;65508:1;65494:16;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65494:16:0;65487:23;;65539:5;65529:4;65534:1;65529:7;;;;;;;;;;;;;:15;-1:-1:-1;;;;;65529:15:0;;;-1:-1:-1;;;;;65529:15:0;;;;;65573:3;65563:4;65568:1;65563:7;;;;;;;65434:321;65624:16;;;65638:1;65624:16;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65624:16:0;65617:23;;65669:5;65659:4;65664:1;65659:7;;;;;;;;;;;;;:15;-1:-1:-1;;;;;65659:15:0;;;-1:-1:-1;;;;;65659:15:0;;;;;56619:42;65693:4;65698:1;65693:7;;;;;;;;;;;;;:14;-1:-1:-1;;;;;65693:14:0;;;-1:-1:-1;;;;;65693:14:0;;;;;65736:3;65726:4;65731:1;65726:7;;;;;;;;;;;;;:13;-1:-1:-1;;;;;65726:13:0;;;-1:-1:-1;;;;;65726:13:0;;;;;65434:321;65796:12;;-1:-1:-1;;;;;65796:12:0;65780:54;65849:7;65796:12;65887:4;65914;65934:11;:3;65942:2;65934:7;:11::i;:::-;65780:176;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;65780:176:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;65780:176:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;65780:176:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;65780:176:0;;;;;;;;;;;;-1:-1:-1;65780:176:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64427:1537;;;;:::o;60302:302::-;60416:10;;60366:15;;-1:-1:-1;;;;;60416:10:0;60402;:24;60394:48;;;;;-1:-1:-1;;;60394:48:0;;;;;;;;;;;;-1:-1:-1;;;60394:48:0;;;;;;;;;;;;;;;60461:4;;-1:-1:-1;;;;;60461:23:0;;;:4;;:23;;60453:40;;;;;-1:-1:-1;;;60453:40:0;;;;;;;;;;;;;;;-1:-1:-1;;;60453:40:0;;;;;;;;;;;;;;;60514:31;;;-1:-1:-1;;;60514:31:0;;60539:4;60514:31;;;;;;-1:-1:-1;;;;;60514:16:0;;;;;:31;;;;;;;;;;;;;;:16;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;60514:31:0;60576:10;;60514:31;;-1:-1:-1;60556:40:0;;-1:-1:-1;;;;;60556:19:0;;;;60576:10;60514:31;60556:19;:40::i;34482:313::-;34559:9;34570:4;34588:13;34603:18;;:::i;:::-;34625:20;34635:1;34638:6;34625:9;:20::i;:::-;34587:58;;-1:-1:-1;34587:58:0;-1:-1:-1;34667:18:0;34660:3;:25;;;;;;;;;34656:73;;-1:-1:-1;34710:3:0;-1:-1:-1;34715:1:0;;-1:-1:-1;34702:15:0;;34656:73;34749:18;34769:17;34778:7;34769:8;:17::i;:::-;34741:46;;;;;;34482:313;;;;;;:::o;62924:82::-;62968:30;62982:15;:13;:15::i;27262:622::-;27632:10;;;27631:62;;-1:-1:-1;27648:39:0;;;-1:-1:-1;;;27648:39:0;;27672:4;27648:39;;;;-1:-1:-1;;;;;27648:39:0;;;;;;;;;:15;;;;;;:39;;;;;;;;;;;;;;;:15;:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;27648:39:0;:44;27631:62;27623:152;;;;-1:-1:-1;;;27623:152:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27813:62;;;-1:-1:-1;;;;;27813:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;27813:62:0;-1:-1:-1;;;27813:62:0;;;27786:90;;27806:5;;27786:19;:90::i;84754:189::-;84848:24;;84825:4;;-1:-1:-1;;;84848:24:0;;;;:47;;;;-1:-1:-1;84876:5:0;;-1:-1:-1;;;;;84876:5:0;:19;;84848:47;:87;;;;-1:-1:-1;84906:4:0;;84922:5;;84899:29;;;-1:-1:-1;;;84899:29:0;;-1:-1:-1;;;;;84922:5:0;;;84899:29;;;;;;84931:4;;84906;;;;;84899:22;;:29;;;;;;;;;;;;;;;84906:4;84899:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;84899:29:0;:36;;84754:189;-1:-1:-1;;84754:189:0:o;3798:278::-;3884:7;3919:12;3912:5;3904:28;;;;-1:-1:-1;;;3904:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3943:9;3959:1;3955;:5;;;;;;;3798:278;-1:-1:-1;;;;;3798:278:0:o;1772:192::-;1858:7;1894:12;1886:6;;;;1878:29;;;;-1:-1:-1;;;1878:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;1930:5:0;;;1772:192::o;28908:761::-;29332:23;29358:69;29386:4;29358:69;;;;;;;;;;;;;;;;;29366:5;-1:-1:-1;;;;;29358:27:0;;;:69;;;;;:::i;:::-;29442:17;;29332:95;;-1:-1:-1;29442:21:0;29438:224;;29584:10;29573:30;;;;;;;;;;;;;;;-1:-1:-1;29573:30:0;29565:85;;;;-1:-1:-1;;;29565:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34016:353;34085:9;34096:10;;:::i;:::-;34120:14;34136:19;34159:27;34167:1;:10;;;34179:6;34159:7;:27::i;:::-;34119:67;;-1:-1:-1;34119:67:0;-1:-1:-1;34209:18:0;34201:4;:26;;;;;;;;;34197:92;;-1:-1:-1;34258:18:0;;;;;;;;;-1:-1:-1;34258:18:0;;34252:4;;-1:-1:-1;34258:18:0;-1:-1:-1;34244:33:0;;34197:92;34329:31;;;;;;;;;;;;-1:-1:-1;;34329:31:0;;-1:-1:-1;34016:353:0;-1:-1:-1;;;;34016:353:0:o;39293:213::-;39475:12;32328:4;39475:23;;;39293:213::o;12773:196::-;12876:12;12908:53;12931:6;12939:4;12945:1;12948:12;12908:22;:53::i;:::-;12901:60;12773:196;-1:-1:-1;;;;12773:196:0:o;30214:343::-;30270:9;;30302:6;30298:69;;-1:-1:-1;30333:18:0;;-1:-1:-1;30333:18:0;30325:30;;30298:69;30388:5;;;30392:1;30388;:5;:1;30410:5;;;;;:10;30406:144;;30445:26;30473:1;30437:38;;;;;;;30406:144;30516:18;;-1:-1:-1;30536:1:0;-1:-1:-1;30508:30:0;;14150:979;14280:12;14313:18;14324:6;14313:10;:18::i;:::-;14305:60;;;;;-1:-1:-1;;;14305:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;14439:12;14453:23;14480:6;-1:-1:-1;;;;;14480:11:0;14500:8;14511:4;14480:36;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;14480:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14438:78;;;;14531:7;14527:595;;;14562:10;-1:-1:-1;14555:17:0;;-1:-1:-1;14555:17:0;14527:595;14676:17;;:21;14672:439;;14939:10;14933:17;15000:15;14987:10;14983:2;14979:19;14972:44;14887:148;15075:20;;-1:-1:-1;;;15075:20:0;;;;;;;;;;;;;;;;;15082:12;;15075:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9658:619;9718:4;10186:20;;10029:66;10226:23;;;;;;:42;;-1:-1:-1;;10253:15:0;;;10218:51;-1:-1:-1;;9658:619:0:o;-1:-1:-1:-;;;;;;;;;;;;;;:::o
Swarm Source
ipfs://b00e35e72a8c459b3d7b2c65cec4b381d84733f0e1a8539f8f6e26c074ebaddd
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 27 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.